From 8db9e29f61870791cdf4dfad96b62d69f9179990 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 24 May 2026 02:36:24 +0200 Subject: [PATCH] update next-breaking (#11999) --- .github/actions/migration/action.yaml | 4 +- .github/actions/setup/action.yaml | 8 + .github/scripts/check_exported_data.py | 101 + .github/workflows/docker.yaml | 14 +- .github/workflows/import_export.yaml | 120 + .github/workflows/qc_checks.yaml | 112 +- .github/workflows/release.yaml | 57 +- .github/workflows/scorecard.yaml | 4 +- .github/workflows/translations.yaml | 4 +- .pkgr.yml | 1 + .pre-commit-config.yaml | 17 +- .vscode/launch.json | 4 +- CHANGELOG.md | 46 +- CONTRIBUTING.md | 1 - README.md | 1 + codecov.yml | 3 + contrib/container/Dockerfile | 4 +- contrib/container/requirements.txt | 217 +- contrib/dev_reqs/requirements.in | 2 +- contrib/dev_reqs/requirements.txt | 280 +- docs/docs/api/index.md | 4 +- docs/docs/api/schema.md | 2 +- docs/docs/app/build.md | 35 + docs/docs/app/po.md | 2 +- docs/docs/app/settings.md | 2 +- docs/docs/assets/images/app/build_detail.png | Bin 0 -> 134142 bytes docs/docs/assets/images/app/build_list.png | Bin 0 -> 272053 bytes docs/docs/assets/images/app/build_outputs.png | Bin 0 -> 99137 bytes .../images/app/build_required_parts.png | Bin 0 -> 143470 bytes docs/docs/assets/images/build/bom_compare.png | Bin 0 -> 43496 bytes .../assets/images/build/bom_compare_icon.png | Bin 0 -> 135286 bytes .../assets/images/build/replace_component.png | Bin 0 -> 153690 bytes .../images/concepts/ui_form_add_part.png | Bin 35305 -> 50894 bytes docs/docs/assets/images/faq/boundary.png | Bin 0 -> 29842 bytes .../images/stock/transfer_order_calendar.png | Bin 0 -> 44399 bytes .../images/stock/transfer_order_display.png | Bin 0 -> 89501 bytes .../images/stock/transfer_order_list.png | Bin 0 -> 56809 bytes docs/docs/concepts/attachments.md | 33 + docs/docs/concepts/custom_states.md | 72 +- docs/docs/concepts/data_export.md | 72 + .../import.md => concepts/data_import.md} | 8 +- docs/docs/concepts/parameters.md | 14 +- docs/docs/concepts/threat_model.md | 2 +- docs/docs/concepts/units.md | 4 +- docs/docs/concepts/user_interface.md | 9 +- docs/docs/develop/contributing.md | 20 +- docs/docs/develop/devcontainer.md | 7 +- docs/docs/faq.md | 11 + docs/docs/hooks.py | 20 +- docs/docs/manufacturing/bom.md | 129 +- docs/docs/manufacturing/build.md | 3 +- docs/docs/manufacturing/required.md | 90 + docs/docs/part/create.md | 4 +- docs/docs/part/index.md | 21 +- docs/docs/part/revision.md | 17 +- docs/docs/plugins/develop.md | 2 +- docs/docs/plugins/frontend.md | 23 +- docs/docs/plugins/install.md | 3 + docs/docs/plugins/mixins/app.md | 24 + docs/docs/plugins/mixins/event.md | 3 + docs/docs/plugins/mixins/ui.md | 14 + docs/docs/plugins/test.md | 9 +- docs/docs/report/helpers.md | 165 +- docs/docs/sales/sales_order.md | 1 + docs/docs/settings/SSO.md | 8 +- docs/docs/settings/admin.md | 9 +- docs/docs/settings/error_codes.md | 16 + docs/docs/settings/export.md | 25 - docs/docs/settings/global.md | 22 +- docs/docs/settings/permissions.md | 14 +- docs/docs/settings/user.md | 2 + docs/docs/start/advanced.md | 73 +- docs/docs/start/backup.md | 26 +- docs/docs/start/config.md | 333 +- docs/docs/start/docker_install.md | 14 +- docs/docs/start/installer.md | 11 +- docs/docs/start/migrate.md | 33 + docs/docs/start/processes.md | 23 +- docs/docs/stock/index.md | 2 +- docs/docs/stock/traceability.md | 2 + docs/docs/stock/transfer_order.md | 150 + docs/main.py | 30 + docs/mkdocs.yml | 7 +- docs/requirements.in | 2 +- docs/requirements.txt | 431 +- pyproject.toml | 10 +- src/backend/InvenTree/.gitignore | 1 + src/backend/InvenTree/InvenTree/api.py | 87 +- .../InvenTree/InvenTree/api_version.py | 124 +- src/backend/InvenTree/InvenTree/apps.py | 6 +- src/backend/InvenTree/InvenTree/cache.py | 81 +- src/backend/InvenTree/InvenTree/config.py | 47 +- src/backend/InvenTree/InvenTree/conversion.py | 8 +- src/backend/InvenTree/InvenTree/exceptions.py | 2 +- src/backend/InvenTree/InvenTree/filters.py | 34 +- src/backend/InvenTree/InvenTree/helpers.py | 107 +- .../InvenTree/InvenTree/helpers_api.py | 49 + .../InvenTree/InvenTree/helpers_email.py | 3 +- .../InvenTree/InvenTree/helpers_model.py | 85 +- src/backend/InvenTree/InvenTree/logging.py | 17 + .../commands/export_settings_definitions.py | 15 +- .../management/commands/list_apps.py | 29 + .../management/commands/migrate_icons.py | 2 +- .../management/commands/rebuild_thumbnails.py | 5 +- .../management/commands/wait_for_db.py | 34 +- src/backend/InvenTree/InvenTree/metadata.py | 27 +- src/backend/InvenTree/InvenTree/middleware.py | 34 +- src/backend/InvenTree/InvenTree/mixins.py | 45 +- src/backend/InvenTree/InvenTree/models.py | 38 +- .../InvenTree/InvenTree/permissions.py | 2 +- src/backend/InvenTree/InvenTree/ready.py | 102 +- src/backend/InvenTree/InvenTree/sanitizer.py | 148 +- src/backend/InvenTree/InvenTree/schema.py | 41 +- .../InvenTree/InvenTree/serializers.py | 521 +- .../InvenTree/InvenTree/setting/db_backend.py | 230 + .../InvenTree/InvenTree/setting/ldap.py | 139 + .../InvenTree/InvenTree/setting/tracing.py | 61 + .../InvenTree/InvenTree/setting/worker.py | 88 + src/backend/InvenTree/InvenTree/settings.py | 489 +- src/backend/InvenTree/InvenTree/sso.py | 2 +- src/backend/InvenTree/InvenTree/tasks.py | 119 +- src/backend/InvenTree/InvenTree/test_api.py | 10 +- .../InvenTree/InvenTree/test_serializers.py | 132 +- src/backend/InvenTree/InvenTree/test_tasks.py | 80 +- src/backend/InvenTree/InvenTree/tests.py | 30 +- src/backend/InvenTree/InvenTree/tracing.py | 2 +- src/backend/InvenTree/InvenTree/urls.py | 1 + src/backend/InvenTree/InvenTree/version.py | 12 +- src/backend/InvenTree/build/api.py | 197 +- src/backend/InvenTree/build/models.py | 159 +- src/backend/InvenTree/build/serializers.py | 427 +- src/backend/InvenTree/build/tasks.py | 303 +- src/backend/InvenTree/build/test_api.py | 94 +- src/backend/InvenTree/build/test_build.py | 349 +- src/backend/InvenTree/common/admin.py | 18 + src/backend/InvenTree/common/api.py | 424 +- src/backend/InvenTree/common/currency.py | 2 +- src/backend/InvenTree/common/filters.py | 55 +- ...ttachment_is_image_attachment_thumbnail.py | 48 + .../migrations/0043_auto_20260518_1206.py | 58 + src/backend/InvenTree/common/models.py | 247 +- src/backend/InvenTree/common/serializers.py | 128 +- .../InvenTree/common/setting/system.py | 114 +- src/backend/InvenTree/common/setting/type.py | 2 + src/backend/InvenTree/common/setting/user.py | 14 + src/backend/InvenTree/common/settings.py | 17 +- src/backend/InvenTree/common/tasks.py | 18 + src/backend/InvenTree/common/test_api.py | 362 + src/backend/InvenTree/common/test_emails.py | 4 +- .../InvenTree/common/test_migrations.py | 81 + src/backend/InvenTree/common/tests.py | 99 +- src/backend/InvenTree/common/validators.py | 18 +- src/backend/InvenTree/company/api.py | 10 +- src/backend/InvenTree/company/models.py | 9 +- src/backend/InvenTree/company/serializers.py | 204 +- src/backend/InvenTree/company/test_api.py | 2 + .../InvenTree/company/test_migrations.py | 2 +- src/backend/InvenTree/config_template.yaml | 12 +- .../InvenTree/generic/states/fields.py | 6 +- src/backend/InvenTree/generic/states/tests.py | 6 +- .../InvenTree/generic/states/transition.py | 2 +- src/backend/InvenTree/importer/api.py | 16 + src/backend/InvenTree/importer/mixins.py | 4 +- src/backend/InvenTree/importer/models.py | 23 +- src/backend/InvenTree/importer/registry.py | 6 +- src/backend/InvenTree/importer/tests.py | 32 +- .../InvenTree/locale/ar/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/bg/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/cs/LC_MESSAGES/django.po | 3962 +++---- .../InvenTree/locale/da/LC_MESSAGES/django.po | 4082 +++---- .../InvenTree/locale/de/LC_MESSAGES/django.po | 3984 +++---- .../InvenTree/locale/el/LC_MESSAGES/django.po | 3952 +++---- .../InvenTree/locale/en/LC_MESSAGES/django.po | 4074 +++---- .../InvenTree/locale/es/LC_MESSAGES/django.po | 3956 +++---- .../locale/es_MX/LC_MESSAGES/django.po | 3978 +++---- .../InvenTree/locale/et/LC_MESSAGES/django.po | 4082 +++---- .../InvenTree/locale/fa/LC_MESSAGES/django.po | 4078 +++---- .../InvenTree/locale/fi/LC_MESSAGES/django.po | 4044 +++---- .../InvenTree/locale/fr/LC_MESSAGES/django.po | 3952 +++---- .../InvenTree/locale/he/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/hi/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/hu/LC_MESSAGES/django.po | 3980 +++---- .../InvenTree/locale/id/LC_MESSAGES/django.po | 4090 +++---- .../InvenTree/locale/it/LC_MESSAGES/django.po | 3956 +++---- .../InvenTree/locale/ja/LC_MESSAGES/django.po | 3954 +++---- .../InvenTree/locale/ko/LC_MESSAGES/django.po | 9318 ++++++++-------- .../InvenTree/locale/lt/LC_MESSAGES/django.po | 3952 +++---- .../InvenTree/locale/lv/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/nl/LC_MESSAGES/django.po | 4014 +++---- .../InvenTree/locale/no/LC_MESSAGES/django.po | 3978 +++---- .../InvenTree/locale/pl/LC_MESSAGES/django.po | 3956 +++---- .../InvenTree/locale/pt/LC_MESSAGES/django.po | 3974 +++---- .../locale/pt_BR/LC_MESSAGES/django.po | 3956 +++---- .../InvenTree/locale/ro/LC_MESSAGES/django.po | 4414 ++++---- .../InvenTree/locale/ru/LC_MESSAGES/django.po | 3952 +++---- .../InvenTree/locale/sk/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/sl/LC_MESSAGES/django.po | 4080 +++---- .../InvenTree/locale/sr/LC_MESSAGES/django.po | 3974 +++---- .../InvenTree/locale/sv/LC_MESSAGES/django.po | 4092 +++---- .../InvenTree/locale/th/LC_MESSAGES/django.po | 4076 +++---- .../InvenTree/locale/tr/LC_MESSAGES/django.po | 4310 ++++---- .../InvenTree/locale/uk/LC_MESSAGES/django.po | 4088 +++---- .../InvenTree/locale/vi/LC_MESSAGES/django.po | 3978 +++---- .../locale/zh_Hans/LC_MESSAGES/django.po | 4034 +++---- .../locale/zh_Hant/LC_MESSAGES/django.po | 4184 +++---- src/backend/InvenTree/machine/api.py | 8 +- .../machine/machine_types/label_printer.py | 2 +- src/backend/InvenTree/machine/serializers.py | 2 +- src/backend/InvenTree/machine/test_api.py | 4 +- src/backend/InvenTree/machine/tests.py | 4 +- src/backend/InvenTree/manage.py | 6 +- src/backend/InvenTree/order/admin.py | 38 + src/backend/InvenTree/order/api.py | 712 +- src/backend/InvenTree/order/events.py | 9 + .../order/fixtures/transfer_order.yaml | 68 + ...ated_at_returnorder_updated_at_and_more.py | 43 + ...16_purchaseorderextraline_line_and_more.py | 79 + ...urchaseorderextraline_line_int_and_more.py | 74 + .../order/migrations/0118_transferorder.py | 482 + .../0119_transferorderlineitem_line_int.py | 18 + src/backend/InvenTree/order/models.py | 952 +- src/backend/InvenTree/order/serializers.py | 1132 +- src/backend/InvenTree/order/status_codes.py | 27 + src/backend/InvenTree/order/tasks.py | 41 +- src/backend/InvenTree/order/test_api.py | 995 +- .../InvenTree/order/test_sales_order.py | 89 + src/backend/InvenTree/order/tests.py | 163 +- src/backend/InvenTree/order/validators.py | 21 + src/backend/InvenTree/part/api.py | 108 +- src/backend/InvenTree/part/filters.py | 49 +- src/backend/InvenTree/part/fixtures/bom.yaml | 6 + src/backend/InvenTree/part/helpers.py | 8 +- .../migrations/0145_auto_20251203_1238.py | 2 + .../migrations/0148_auto_20260427_2233.py | 44 + .../migrations/0149_bomitem_raw_amount.py | 86 + .../migrations/0150_part_maximum_stock.py | 26 + src/backend/InvenTree/part/models.py | 223 +- src/backend/InvenTree/part/serializers.py | 434 +- src/backend/InvenTree/part/stocktake.py | 2 +- src/backend/InvenTree/part/tasks.py | 1 + src/backend/InvenTree/part/test_api.py | 408 +- src/backend/InvenTree/part/test_bom_item.py | 119 + src/backend/InvenTree/part/test_category.py | 4 +- .../InvenTree/part/test_notification_stale.py | 6 +- src/backend/InvenTree/part/test_param.py | 38 + src/backend/InvenTree/part/test_part.py | 36 +- src/backend/InvenTree/plugin/api.py | 7 +- .../InvenTree/plugin/base/barcodes/mixins.py | 2 +- .../plugin/base/integration/AppMixin.py | 7 +- .../plugin/base/integration/DataExport.py | 30 +- .../plugin/base/integration/ReportMixin.py | 12 +- .../plugin/base/integration/test_mixins.py | 53 + .../InvenTree/plugin/base/label/mixins.py | 44 +- .../InvenTree/plugin/base/supplier/mixins.py | 2 +- .../InvenTree/plugin/base/ui/mixins.py | 30 +- src/backend/InvenTree/plugin/base/ui/tests.py | 10 + .../InvenTree/plugin/broken/broken_file.py | 2 +- .../builtin/integration/core_notifications.py | 2 +- .../plugin/builtin/labels/inventree_label.py | 1 + src/backend/InvenTree/plugin/installer.py | 14 +- src/backend/InvenTree/plugin/plugin.py | 120 +- src/backend/InvenTree/plugin/registry.py | 15 +- .../integration/test_validation_sample.py | 6 +- .../integration/user_interface_sample.py | 11 + .../samples/supplier/supplier_sample.py | 22 +- src/backend/InvenTree/plugin/serializers.py | 12 +- src/backend/InvenTree/plugin/test_api.py | 17 +- src/backend/InvenTree/plugin/test_plugin.py | 93 +- src/backend/InvenTree/report/api.py | 45 +- src/backend/InvenTree/report/apps.py | 18 +- ...dated_labeltemplate_updated_by_and_more.py | 64 + src/backend/InvenTree/report/models.py | 175 +- src/backend/InvenTree/report/serializers.py | 23 + src/backend/InvenTree/report/tasks.py | 49 +- .../inventree_transfer_order_report.html | 52 + .../InvenTree/report/templatetags/barcode.py | 2 +- .../InvenTree/report/templatetags/report.py | 470 +- src/backend/InvenTree/report/test_tags.py | 93 +- src/backend/InvenTree/report/tests.py | 159 +- src/backend/InvenTree/stock/api.py | 52 +- .../0119_alter_stockitemtestresult_date.py | 22 + src/backend/InvenTree/stock/models.py | 253 +- src/backend/InvenTree/stock/serializers.py | 215 +- src/backend/InvenTree/stock/test_api.py | 362 +- src/backend/InvenTree/users/api.py | 100 +- .../migrations/0011_auto_20240523_1640.py | 7 +- src/backend/InvenTree/users/models.py | 16 +- src/backend/InvenTree/users/oauth2_scopes.py | 2 + src/backend/InvenTree/users/permissions.py | 5 + src/backend/InvenTree/users/ruleset.py | 34 +- src/backend/InvenTree/users/serializers.py | 77 +- src/backend/InvenTree/users/test_api.py | 152 +- src/backend/InvenTree/web/tests.py | 2 +- src/backend/osv-scanner.toml | 5 + src/backend/requirements-3.14.txt | 1688 +-- src/backend/requirements-dev-3.14.txt | 854 +- src/backend/requirements-dev.in | 2 +- src/backend/requirements-dev.txt | 940 +- src/backend/requirements.in | 6 +- src/backend/requirements.txt | 1687 +-- src/frontend/.gitignore | 3 + src/frontend/CHANGELOG.md | 72 + .../{src => lib}/components/Boundary.tsx | 9 +- .../buttons => lib/components}/CopyButton.tsx | 9 +- .../components}/CopyableCell.tsx | 2 +- .../lib/components/InvenTreeTable.tsx | 63 + src/frontend/lib/components/RowActions.tsx | 4 +- .../items => lib/components}/StylishText.tsx | 0 .../components/TableColumnSelect.tsx} | 0 .../components/nav/DetailDrawer.css.ts | 0 .../components/nav/DetailDrawer.tsx | 13 +- src/frontend/lib/enums/ApiEndpoints.tsx | 23 +- src/frontend/lib/enums/ModelInformation.tsx | 24 + src/frontend/lib/enums/ModelType.tsx | 16 + src/frontend/lib/enums/Roles.tsx | 4 + src/frontend/lib/functions/Forms.tsx | 47 + src/frontend/lib/functions/Notification.tsx | 50 + .../tables.tsx => lib/functions/String.tsx} | 0 .../lib/hooks/MonitorBackgroundTask.tsx | 118 + src/frontend/lib/hooks/MonitorDataOutput.tsx | 124 + .../{src => lib}/hooks/UseFilterSet.tsx | 20 +- src/frontend/{src => lib}/hooks/UseTable.tsx | 19 +- src/frontend/lib/index.ts | 83 +- src/frontend/lib/states/LocalLibState.tsx | 23 + .../{src => lib}/states/StoredTableState.tsx | 2 +- src/frontend/lib/states/types.tsx | 7 + src/frontend/lib/types/Forms.tsx | 23 +- src/frontend/lib/types/Icons.tsx | 6 +- .../components/panels => lib/types}/Panel.tsx | 9 +- src/frontend/lib/types/Plugins.tsx | 51 +- src/frontend/lib/types/Rendering.tsx | 60 + src/frontend/lib/types/Tables.tsx | 31 +- src/frontend/package.json | 118 +- src/frontend/playwright.config.ts | 9 + src/frontend/playwright/global-setup.ts | 20 +- .../src/components/barcodes/BarcodeInput.tsx | 2 +- .../components/barcodes/BarcodeScanDialog.tsx | 2 +- .../src/components/barcodes/QRCode.tsx | 2 +- .../buttons/PrimaryActionButton.tsx | 6 +- .../buttons/StarredToggleButton.tsx | 4 +- .../src/components/calendar/Calendar.tsx | 59 +- .../src/components/calendar/OrderCalendar.tsx | 17 +- .../calendar/OrderCalendarToolTip.tsx | 61 + .../components/dashboard/DashboardLayout.tsx | 32 +- .../components/dashboard/DashboardMenu.tsx | 2 +- .../components/dashboard/DashboardWidget.tsx | 2 +- .../dashboard/DashboardWidgetDrawer.tsx | 2 +- .../dashboard/DashboardWidgetLibrary.tsx | 22 +- .../dashboard/widgets/ColorToggleWidget.tsx | 2 +- .../dashboard/widgets/GetStartedWidget.tsx | 2 +- .../widgets/LanguageSelectWidget.tsx | 2 +- .../dashboard/widgets/NewsWidget.tsx | 2 +- .../widgets/QueryCountDashboardWidget.tsx | 18 +- .../widgets/QueryDashboardWidget.tsx | 96 + .../src/components/details/Details.tsx | 28 +- .../src/components/details/DetailsImage.tsx | 108 +- .../src/components/editors/NotesEditor.tsx | 13 +- .../TemplateEditor/CodeEditor/index.tsx | 8 +- .../TemplateEditor/PdfPreview/PdfPreview.tsx | 6 +- .../TemplateEditor/PdfPreview/index.tsx | 8 +- .../editors/TemplateEditor/TemplateEditor.tsx | 2 +- src/frontend/src/components/forms/ApiForm.tsx | 51 +- .../src/components/forms/InstanceOptions.tsx | 3 +- .../components/forms/KeepFormOpenSwitch.tsx | 23 + .../components/forms/fields/ApiFormField.tsx | 10 +- .../forms/fields/RelatedModelField.tsx | 217 +- .../components/forms/fields/TableField.tsx | 11 - .../src/components/forms/fields/TextField.tsx | 12 +- .../src/components/images/ApiImage.tsx | 53 +- .../src/components/images/Thumbnail.tsx | 16 +- .../importer/GlobalImporterDrawer.tsx | 22 + .../importer/ImportDataSelector.tsx | 49 +- .../importer/ImporterColumnSelector.tsx | 26 +- .../components/importer/ImporterDrawer.tsx | 16 +- .../components/importer/ImporterStatus.tsx | 2 +- .../src/components/items/ActionDropdown.tsx | 2 +- .../src/components/items/AttachmentLink.tsx | 11 +- .../items/GettingStartedCarousel.tsx | 2 +- .../src/components/items/InfoItem.tsx | 2 +- .../src/components/items/LanguageSelect.tsx | 2 +- .../src/components/items/MenuLinks.tsx | 2 +- .../src/components/items/OnlyStaff.tsx | 4 +- .../components/modals/AboutInvenTreeModal.tsx | 23 +- .../src/components/modals/QrModal.tsx | 8 +- src/frontend/src/components/nav/Header.tsx | 52 +- src/frontend/src/components/nav/Layout.tsx | 56 +- .../src/components/nav/NavigationDrawer.tsx | 2 +- .../src/components/nav/NavigationTree.tsx | 2 +- .../src/components/nav/NotificationDrawer.tsx | 6 +- .../src/components/nav/PageDetail.tsx | 56 +- .../src/components/nav/SearchDrawer.tsx | 44 +- .../src/components/nav/SettingsHeader.tsx | 2 +- .../src/components/panels/AttachmentPanel.tsx | 19 +- .../src/components/panels/NotesPanel.tsx | 9 +- .../src/components/panels/PanelGroup.tsx | 249 +- .../src/components/panels/ParametersPanel.tsx | 20 +- .../panels/SegmentedControlPanel.tsx | 2 +- .../src/components/plugins/PluginContext.tsx | 41 +- .../src/components/plugins/PluginDrawer.tsx | 2 +- .../components/plugins/PluginUIFeature.tsx | 3 +- .../plugins/PluginUIFeatureTypes.ts | 8 + .../components/plugins/RemoteComponent.tsx | 2 +- src/frontend/src/components/render/Build.tsx | 10 +- .../src/components/render/Company.tsx | 8 +- .../src/components/render/Generic.tsx | 24 +- .../src/components/render/Instance.tsx | 64 +- .../src/components/render/InstanceFromUrl.tsx | 33 - src/frontend/src/components/render/Order.tsx | 43 + src/frontend/src/components/render/Part.tsx | 6 +- src/frontend/src/components/render/Stock.tsx | 2 +- .../src/components/settings/FactItem.tsx | 2 +- .../src/components/settings/SettingItem.tsx | 2 +- .../components/wizards/OrderPartsWizard.tsx | 51 +- .../src/components/wizards/WizardDrawer.tsx | 4 +- src/frontend/src/contexts/LanguageContext.tsx | 2 +- src/frontend/src/contexts/ThemeContext.tsx | 3 +- src/frontend/src/defaults/backendMappings.tsx | 2 + src/frontend/src/defaults/defaultHostList.tsx | 14 + src/frontend/src/defaults/links.tsx | 2 +- src/frontend/src/forms/BomForms.tsx | 13 +- src/frontend/src/forms/BuildForms.tsx | 18 +- src/frontend/src/forms/CommonForms.tsx | 126 +- src/frontend/src/forms/CompanyForms.tsx | 29 +- src/frontend/src/forms/PartForms.tsx | 29 +- src/frontend/src/forms/PurchaseOrderForms.tsx | 83 +- src/frontend/src/forms/ReturnOrderForms.tsx | 6 +- src/frontend/src/forms/SalesOrderForms.tsx | 52 +- src/frontend/src/forms/StockForms.tsx | 39 +- src/frontend/src/forms/TransferOrderForms.tsx | 308 + src/frontend/src/functions/auth.tsx | 4 + src/frontend/src/functions/forms.tsx | 50 +- src/frontend/src/functions/icons.tsx | 4 + src/frontend/src/functions/notifications.tsx | 49 - src/frontend/src/hooks/UseBackgroundTask.tsx | 18 + src/frontend/src/hooks/UseCalendar.tsx | 2 +- src/frontend/src/hooks/UseDataOutput.tsx | 109 +- src/frontend/src/hooks/UseForm.tsx | 24 +- src/frontend/src/hooks/UseGenerator.tsx | 2 +- src/frontend/src/hooks/UseInstance.tsx | 48 +- src/frontend/src/hooks/UseModal.tsx | 2 +- src/frontend/src/hooks/UsePluginPanels.tsx | 6 +- .../src/hooks/UseStockAdjustActions.tsx | 14 + src/frontend/src/locales/ar/messages.po | 5433 ++++----- src/frontend/src/locales/bg/messages.po | 5427 ++++----- src/frontend/src/locales/cs/messages.po | 5449 ++++----- src/frontend/src/locales/da/messages.po | 5431 ++++----- src/frontend/src/locales/de/messages.po | 5639 +++++----- src/frontend/src/locales/el/messages.po | 5449 ++++----- src/frontend/src/locales/en/messages.po | 5445 ++++----- src/frontend/src/locales/es/messages.po | 5453 ++++----- src/frontend/src/locales/es_MX/messages.po | 5501 ++++----- src/frontend/src/locales/et/messages.po | 6209 ++++++----- src/frontend/src/locales/fa/messages.po | 5427 ++++----- src/frontend/src/locales/fi/messages.po | 5427 ++++----- src/frontend/src/locales/fr/messages.po | 5449 ++++----- src/frontend/src/locales/he/messages.po | 5435 ++++----- src/frontend/src/locales/hi/messages.po | 5427 ++++----- src/frontend/src/locales/hu/messages.po | 5481 ++++----- src/frontend/src/locales/id/messages.po | 5429 ++++----- src/frontend/src/locales/it/messages.po | 5449 ++++----- src/frontend/src/locales/ja/messages.po | 5449 ++++----- src/frontend/src/locales/ko/messages.po | 9787 +++++++++-------- src/frontend/src/locales/lt/messages.po | 5431 ++++----- src/frontend/src/locales/lv/messages.po | 5427 ++++----- src/frontend/src/locales/nl/messages.po | 5465 ++++----- src/frontend/src/locales/no/messages.po | 5411 ++++----- src/frontend/src/locales/pl/messages.po | 5441 ++++----- src/frontend/src/locales/pt/messages.po | 5429 ++++----- src/frontend/src/locales/pt_BR/messages.po | 5445 ++++----- src/frontend/src/locales/ro/messages.po | 5555 +++++----- src/frontend/src/locales/ru/messages.po | 5449 ++++----- src/frontend/src/locales/sk/messages.po | 5427 ++++----- src/frontend/src/locales/sl/messages.po | 5455 ++++----- src/frontend/src/locales/sr/messages.po | 5443 ++++----- src/frontend/src/locales/sv/messages.po | 5469 ++++----- src/frontend/src/locales/th/messages.po | 5427 ++++----- src/frontend/src/locales/tr/messages.po | 5437 ++++----- src/frontend/src/locales/uk/messages.po | 5425 ++++----- src/frontend/src/locales/vi/messages.po | 5477 ++++----- src/frontend/src/locales/zh_Hans/messages.po | 5657 +++++----- src/frontend/src/locales/zh_Hant/messages.po | 7173 ++++++------ src/frontend/src/main.css.ts | 24 +- src/frontend/src/main.tsx | 35 +- .../src/pages/Auth/ChangePassword.tsx | 2 +- src/frontend/src/pages/Auth/Layout.tsx | 2 +- src/frontend/src/pages/Auth/Login.tsx | 9 +- src/frontend/src/pages/Index/Scan.tsx | 8 +- .../AccountSettings/AccountDetailPanel.tsx | 6 +- .../Settings/AccountSettings/MFASettings.tsx | 4 +- .../AccountSettings/QrRegistrationForm.tsx | 2 +- .../AccountSettings/SecurityContent.tsx | 4 +- .../Settings/AccountSettings/UserPanel.tsx | 22 +- .../AccountSettings/UserThemePanel.tsx | 2 +- .../AdminCenter/CurrencyManagementPanel.tsx | 2 +- .../AdminCenter/EmailManagementPanel.tsx | 2 +- .../Index/Settings/AdminCenter/HomePanel.tsx | 2 +- .../Index/Settings/AdminCenter/Index.tsx | 10 +- .../AdminCenter/MachineManagementPanel.tsx | 2 +- .../Settings/AdminCenter/ParameterPanel.tsx | 2 +- .../AdminCenter/PluginManagementPanel.tsx | 28 +- .../AdminCenter/ReportTemplatePanel.tsx | 8 +- .../AdminCenter/TaskManagementPanel.tsx | 17 +- .../AdminCenter/UnitManagementPanel.tsx | 4 +- .../AdminCenter/UserManagementPanel.tsx | 2 +- .../Index/Settings/PluginSettingsGroup.tsx | 26 +- .../pages/Index/Settings/SystemSettings.tsx | 353 +- .../src/pages/Index/Settings/UserSettings.tsx | 22 +- src/frontend/src/pages/Notifications.tsx | 4 +- src/frontend/src/pages/build/BuildDetail.tsx | 45 +- src/frontend/src/pages/build/BuildIndex.tsx | 38 +- .../src/pages/company/CompanyDetail.tsx | 2 +- .../pages/company/ManufacturerPartDetail.tsx | 2 +- .../src/pages/company/SupplierPartDetail.tsx | 10 +- src/frontend/src/pages/core/CoreIndex.tsx | 8 +- src/frontend/src/pages/core/GroupDetail.tsx | 4 +- src/frontend/src/pages/core/UserDetail.tsx | 12 +- .../src/pages/part/CategoryDetail.tsx | 27 +- .../src/pages/part/PartAllocationPanel.tsx | 2 +- src/frontend/src/pages/part/PartDetail.tsx | 345 +- .../src/pages/part/PartStockHistoryDetail.tsx | 6 +- .../src/pages/part/PartSupplierDetail.tsx | 2 +- .../src/pages/part/bom/BomActions.tsx | 191 + .../src/pages/part/bom/BomCompare.tsx | 428 + .../pages/part/pricing/BomPricingPanel.tsx | 3 +- .../pages/part/pricing/PriceBreakPanel.tsx | 2 +- .../src/pages/part/pricing/PricingPanel.tsx | 2 +- .../part/pricing/PurchaseHistoryPanel.tsx | 2 +- .../pages/part/pricing/SaleHistoryPanel.tsx | 2 +- .../part/pricing/SupplierPricingPanel.tsx | 2 +- .../part/pricing/VariantPricingPanel.tsx | 2 +- .../pages/purchasing/PurchaseOrderDetail.tsx | 21 +- .../src/pages/purchasing/PurchasingIndex.tsx | 44 +- .../src/pages/sales/ReturnOrderDetail.tsx | 13 +- src/frontend/src/pages/sales/SalesIndex.tsx | 76 +- .../src/pages/sales/SalesOrderDetail.tsx | 21 +- .../pages/sales/SalesOrderShipmentDetail.tsx | 29 +- .../src/pages/stock/LocationDetail.tsx | 89 +- src/frontend/src/pages/stock/StockDetail.tsx | 90 +- .../src/pages/stock/TransferOrderDetail.tsx | 552 + src/frontend/src/router.tsx | 5 + src/frontend/src/states/IconState.tsx | 2 +- src/frontend/src/states/ImporterState.tsx | 68 + src/frontend/src/states/LocalState.tsx | 15 +- src/frontend/src/states/PluginState.tsx | 41 + src/frontend/src/states/UserState.tsx | 2 +- src/frontend/src/tables/ColumnRenderers.tsx | 41 +- src/frontend/src/tables/Filter.tsx | 36 + .../src/tables/FilterSelectDrawer.tsx | 2 +- src/frontend/src/tables/InvenTreeTable.tsx | 154 +- .../src/tables/InvenTreeTableHeader.tsx | 27 +- src/frontend/src/tables/TableHoverCard.tsx | 2 +- .../src/tables/bom/BomSubassemblyTable.tsx | 123 + src/frontend/src/tables/bom/BomTable.tsx | 193 +- src/frontend/src/tables/bom/UsedInTable.tsx | 101 +- .../tables/build/BuildAllocatedStockTable.tsx | 27 +- .../src/tables/build/BuildLineTable.tsx | 45 +- .../src/tables/build/BuildOrderFilters.tsx | 87 + .../build/BuildOrderParametricTable.tsx | 12 +- .../src/tables/build/BuildOrderTable.tsx | 79 +- .../src/tables/build/BuildOutputTable.tsx | 98 +- .../src/tables/company/AddressTable.tsx | 2 +- .../src/tables/company/CompanyTable.tsx | 5 +- .../src/tables/company/ContactTable.tsx | 2 +- .../tables/company/ParametricCompanyTable.tsx | 12 + .../src/tables/general/AttachmentTable.tsx | 28 +- .../src/tables/general/BarcodeScanTable.tsx | 2 +- .../src/tables/general/ExtraLineItemTable.tsx | 5 +- .../src/tables/general/ParameterTable.tsx | 25 +- .../tables/general/ParameterTemplateTable.tsx | 16 +- .../tables/general/ParametricDataTable.tsx | 4 +- .../src/tables/machine/MachineListTable.tsx | 12 +- .../src/tables/machine/MachineTypeTable.tsx | 6 +- .../src/tables/part/ParametricPartTable.tsx | 22 +- .../tables/part/PartBuildAllocationsTable.tsx | 2 +- .../src/tables/part/PartCategoryTable.tsx | 7 +- .../tables/part/PartCategoryTemplateTable.tsx | 2 +- .../tables/part/PartPurchaseOrdersTable.tsx | 2 +- .../tables/part/PartSalesAllocationsTable.tsx | 2 +- src/frontend/src/tables/part/PartTable.tsx | 192 +- .../src/tables/part/PartTableFilters.tsx | 146 + .../src/tables/part/PartTestResultTable.tsx | 2 +- .../src/tables/part/PartTestTemplateTable.tsx | 2 +- .../src/tables/part/PartThumbTable.tsx | 21 +- .../src/tables/part/RelatedPartTable.tsx | 3 +- .../src/tables/part/SelectionListTable.tsx | 2 +- .../src/tables/plugin/PluginErrorTable.tsx | 2 +- .../src/tables/plugin/PluginListTable.tsx | 16 +- .../purchasing/ManufacturerPartTable.tsx | 5 +- .../purchasing/PurchaseOrderFilters.tsx | 66 + .../purchasing/PurchaseOrderLineItemTable.tsx | 35 +- .../PurchaseOrderParametricTable.tsx | 18 +- .../tables/purchasing/PurchaseOrderTable.tsx | 65 +- .../tables/purchasing/SupplierPartTable.tsx | 5 +- .../purchasing/SupplierPriceBreakTable.tsx | 2 +- .../src/tables/sales/ReturnOrderFilters.tsx | 73 + .../tables/sales/ReturnOrderLineItemTable.tsx | 9 +- .../sales/ReturnOrderParametricTable.tsx | 18 +- .../src/tables/sales/ReturnOrderTable.tsx | 72 +- .../sales/SalesOrderAllocationTable.tsx | 2 +- .../src/tables/sales/SalesOrderFilters.tsx | 73 + .../tables/sales/SalesOrderLineItemTable.tsx | 14 +- .../sales/SalesOrderParametricTable.tsx | 18 +- .../tables/sales/SalesOrderShipmentTable.tsx | 19 +- .../src/tables/sales/SalesOrderTable.tsx | 72 +- .../src/tables/settings/ApiTokenTable.tsx | 10 +- .../settings/BarcodeScanHistoryTable.tsx | 8 +- .../src/tables/settings/CustomStateTable.tsx | 2 +- .../src/tables/settings/CustomUnitsTable.tsx | 2 +- .../src/tables/settings/EmailTable.tsx | 2 +- .../src/tables/settings/ErrorTable.tsx | 6 +- .../tables/settings/ExportSessionTable.tsx | 2 +- .../src/tables/settings/FailedTasksTable.tsx | 4 +- .../src/tables/settings/GroupTable.tsx | 6 +- .../tables/settings/ImportSessionTable.tsx | 24 +- .../src/tables/settings/PendingTasksTable.tsx | 2 +- .../src/tables/settings/ProjectCodeTable.tsx | 2 +- .../tables/settings/ScheduledTasksTable.tsx | 2 +- .../src/tables/settings/TemplateTable.tsx | 44 +- .../src/tables/settings/UserTable.tsx | 15 +- .../src/tables/stock/InstalledItemsTable.tsx | 2 +- .../src/tables/stock/LocationTypesTable.tsx | 2 +- .../src/tables/stock/StockItemTable.tsx | 8 +- .../tables/stock/StockItemTestResultTable.tsx | 4 +- .../src/tables/stock/StockLocationTable.tsx | 7 +- .../src/tables/stock/StockTrackingTable.tsx | 16 +- .../stock/TransferOrderAllocationTable.tsx | 285 + .../stock/TransferOrderLineItemTable.tsx | 529 + .../stock/TransferOrderParametricTable.tsx | 48 + .../src/tables/stock/TransferOrderTable.tsx | 185 + src/frontend/src/window.tsx | 38 + src/frontend/tests/api.ts | 2 +- src/frontend/tests/baseFixtures.ts | 3 +- .../tests/customization/customization.spec.ts | 13 - src/frontend/tests/defaults.ts | 35 +- src/frontend/tests/fixtures/bom_data.csv | 4 +- src/frontend/tests/login.ts | 26 +- src/frontend/tests/pages/pui_build.spec.ts | 145 +- src/frontend/tests/pages/pui_company.spec.ts | 13 +- .../tests/pages/pui_dashboard.spec.ts | 86 + src/frontend/tests/pages/pui_part.spec.ts | 376 +- ...e_order.spec.ts => pui_purchasing.spec.ts} | 151 +- src/frontend/tests/pages/pui_return.spec.ts | 21 + ..._sales_order.spec.ts => pui_sales.spec.ts} | 73 + src/frontend/tests/pages/pui_scan.spec.ts | 8 +- src/frontend/tests/pages/pui_stock.spec.ts | 296 +- src/frontend/tests/pui_exporting.spec.ts | 12 +- src/frontend/tests/pui_forms.spec.ts | 43 +- src/frontend/tests/pui_general.spec.ts | 7 +- src/frontend/tests/pui_importing.spec.ts | 40 +- src/frontend/tests/pui_login.spec.ts | 8 +- src/frontend/tests/pui_machines.spec.ts | 26 +- src/frontend/tests/pui_modals.spec.ts | 4 +- src/frontend/tests/pui_permissions.spec.ts | 17 +- src/frontend/tests/pui_plugins.spec.ts | 16 +- src/frontend/tests/pui_printing.spec.ts | 33 +- src/frontend/tests/pui_settings.spec.ts | 129 +- src/frontend/tests/pui_tables.spec.ts | 10 +- src/frontend/vite.config.ts | 2 +- src/frontend/yarn.lock | 3803 +++---- src/performance/tests.py | 1 + tasks.py | 658 +- 661 files changed, 232019 insertions(+), 191250 deletions(-) create mode 100644 .github/scripts/check_exported_data.py create mode 100644 .github/workflows/import_export.yaml create mode 100644 docs/docs/app/build.md create mode 100644 docs/docs/assets/images/app/build_detail.png create mode 100644 docs/docs/assets/images/app/build_list.png create mode 100644 docs/docs/assets/images/app/build_outputs.png create mode 100644 docs/docs/assets/images/app/build_required_parts.png create mode 100644 docs/docs/assets/images/build/bom_compare.png create mode 100644 docs/docs/assets/images/build/bom_compare_icon.png create mode 100644 docs/docs/assets/images/build/replace_component.png create mode 100644 docs/docs/assets/images/faq/boundary.png create mode 100644 docs/docs/assets/images/stock/transfer_order_calendar.png create mode 100644 docs/docs/assets/images/stock/transfer_order_display.png create mode 100644 docs/docs/assets/images/stock/transfer_order_list.png create mode 100644 docs/docs/concepts/data_export.md rename docs/docs/{settings/import.md => concepts/data_import.md} (93%) create mode 100644 docs/docs/manufacturing/required.md delete mode 100644 docs/docs/settings/export.md create mode 100644 docs/docs/stock/transfer_order.md create mode 100644 src/backend/InvenTree/InvenTree/helpers_api.py create mode 100644 src/backend/InvenTree/InvenTree/logging.py create mode 100644 src/backend/InvenTree/InvenTree/management/commands/list_apps.py create mode 100644 src/backend/InvenTree/InvenTree/setting/db_backend.py create mode 100644 src/backend/InvenTree/InvenTree/setting/ldap.py create mode 100644 src/backend/InvenTree/InvenTree/setting/tracing.py create mode 100644 src/backend/InvenTree/InvenTree/setting/worker.py create mode 100644 src/backend/InvenTree/common/migrations/0042_attachment_is_image_attachment_thumbnail.py create mode 100644 src/backend/InvenTree/common/migrations/0043_auto_20260518_1206.py create mode 100644 src/backend/InvenTree/order/fixtures/transfer_order.yaml create mode 100644 src/backend/InvenTree/order/migrations/0115_purchaseorder_updated_at_returnorder_updated_at_and_more.py create mode 100644 src/backend/InvenTree/order/migrations/0116_purchaseorderextraline_line_and_more.py create mode 100644 src/backend/InvenTree/order/migrations/0117_purchaseorderextraline_line_int_and_more.py create mode 100644 src/backend/InvenTree/order/migrations/0118_transferorder.py create mode 100644 src/backend/InvenTree/order/migrations/0119_transferorderlineitem_line_int.py create mode 100644 src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py create mode 100644 src/backend/InvenTree/part/migrations/0149_bomitem_raw_amount.py create mode 100644 src/backend/InvenTree/part/migrations/0150_part_maximum_stock.py create mode 100644 src/backend/InvenTree/report/migrations/0032_labeltemplate_updated_labeltemplate_updated_by_and_more.py create mode 100644 src/backend/InvenTree/report/templates/report/inventree_transfer_order_report.html create mode 100644 src/backend/InvenTree/stock/migrations/0119_alter_stockitemtestresult_date.py rename src/frontend/{src => lib}/components/Boundary.tsx (73%) rename src/frontend/{src/components/buttons => lib/components}/CopyButton.tsx (89%) rename src/frontend/{src/tables => lib/components}/CopyableCell.tsx (95%) create mode 100644 src/frontend/lib/components/InvenTreeTable.tsx rename src/frontend/{src/components/items => lib/components}/StylishText.tsx (100%) rename src/frontend/{src/tables/ColumnSelect.tsx => lib/components/TableColumnSelect.tsx} (100%) rename src/frontend/{src => lib}/components/nav/DetailDrawer.css.ts (100%) rename src/frontend/{src => lib}/components/nav/DetailDrawer.tsx (89%) create mode 100644 src/frontend/lib/functions/Forms.tsx create mode 100644 src/frontend/lib/functions/Notification.tsx rename src/frontend/{src/functions/tables.tsx => lib/functions/String.tsx} (100%) create mode 100644 src/frontend/lib/hooks/MonitorBackgroundTask.tsx create mode 100644 src/frontend/lib/hooks/MonitorDataOutput.tsx rename src/frontend/{src => lib}/hooks/UseFilterSet.tsx (69%) rename src/frontend/{src => lib}/hooks/UseTable.tsx (86%) create mode 100644 src/frontend/lib/states/LocalLibState.tsx rename src/frontend/{src => lib}/states/StoredTableState.tsx (98%) create mode 100644 src/frontend/lib/states/types.tsx rename src/frontend/{src/components/panels => lib/types}/Panel.tsx (59%) create mode 100644 src/frontend/src/components/calendar/OrderCalendarToolTip.tsx create mode 100644 src/frontend/src/components/dashboard/widgets/QueryDashboardWidget.tsx create mode 100644 src/frontend/src/components/forms/KeepFormOpenSwitch.tsx create mode 100644 src/frontend/src/components/importer/GlobalImporterDrawer.tsx delete mode 100644 src/frontend/src/components/render/InstanceFromUrl.tsx create mode 100644 src/frontend/src/forms/TransferOrderForms.tsx create mode 100644 src/frontend/src/hooks/UseBackgroundTask.tsx create mode 100644 src/frontend/src/pages/part/bom/BomActions.tsx create mode 100644 src/frontend/src/pages/part/bom/BomCompare.tsx create mode 100644 src/frontend/src/pages/stock/TransferOrderDetail.tsx create mode 100644 src/frontend/src/states/ImporterState.tsx create mode 100644 src/frontend/src/states/PluginState.tsx create mode 100644 src/frontend/src/tables/bom/BomSubassemblyTable.tsx create mode 100644 src/frontend/src/tables/build/BuildOrderFilters.tsx create mode 100644 src/frontend/src/tables/part/PartTableFilters.tsx create mode 100644 src/frontend/src/tables/purchasing/PurchaseOrderFilters.tsx create mode 100644 src/frontend/src/tables/sales/ReturnOrderFilters.tsx create mode 100644 src/frontend/src/tables/sales/SalesOrderFilters.tsx create mode 100644 src/frontend/src/tables/stock/TransferOrderAllocationTable.tsx create mode 100644 src/frontend/src/tables/stock/TransferOrderLineItemTable.tsx create mode 100644 src/frontend/src/tables/stock/TransferOrderParametricTable.tsx create mode 100644 src/frontend/src/tables/stock/TransferOrderTable.tsx create mode 100644 src/frontend/src/window.tsx rename src/frontend/tests/pages/{pui_purchase_order.spec.ts => pui_purchasing.spec.ts} (76%) create mode 100644 src/frontend/tests/pages/pui_return.spec.ts rename src/frontend/tests/pages/{pui_sales_order.spec.ts => pui_sales.spec.ts} (78%) diff --git a/.github/actions/migration/action.yaml b/.github/actions/migration/action.yaml index eddec9a9da..2c06172153 100644 --- a/.github/actions/migration/action.yaml +++ b/.github/actions/migration/action.yaml @@ -13,5 +13,5 @@ runs: invoke export-records -f data.json python3 ./src/backend/InvenTree/manage.py flush --noinput invoke migrate - invoke import-records -c -f data.json - invoke import-records -c -f data.json + invoke import-records -c -f data.json --strict + invoke import-records -c -f data.json --strict diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index 38ac61834c..3c7526de71 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -15,6 +15,10 @@ inputs: required: false description: 'Install the InvenTree requirements?' default: 'false' + static: + required: false + description: 'Should the static files be built?' + default: 'false' dev-install: required: false description: 'Install the InvenTree development requirements?' @@ -103,3 +107,7 @@ runs: if: ${{ inputs.update == 'true' }} shell: bash run: invoke update --skip-backup --skip-static + - name: Collect static files + if: ${{ inputs.static == 'true' }} + shell: bash + run: invoke static --skip-plugins diff --git a/.github/scripts/check_exported_data.py b/.github/scripts/check_exported_data.py new file mode 100644 index 0000000000..d7fb78083a --- /dev/null +++ b/.github/scripts/check_exported_data.py @@ -0,0 +1,101 @@ +"""Script to check a data file exported using the 'export-records' command. + +This script is intended to be used as part of the CI workflow, +in conjunction with the "workflows/import_export.yaml" workflow. + +In reads the exported data file, to ensure that: + +- The file can be read and parsed as JSON +- The file contains the expected metadata +- The file contains the expected plugin configuration +- The file contains the expected plugin database records + +""" + +PLUGIN_KEY = 'dummy_app_plugin' +PLUGIN_SLUG = 'dummy-app-plugin' + +import argparse +import json +import os + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Check exported data file') + parser.add_argument('datafile', help='Path to the exported data file (JSON)') + + args = parser.parse_args() + + if not os.path.isfile(args.datafile): + print(f'Error: File not found: {args.datafile}') + exit(1) + + with open(args.datafile, encoding='utf-8') as f: + try: + data = json.load(f) + print(f'Successfully loaded data from {args.datafile}') + print(f'Number of records: {len(data)}') + except json.JSONDecodeError as e: + print(f'Error: Failed to parse JSON file: {e}') + exit(1) + + found_metadata = False + found_installed_apps = False + found_plugin_config = False + plugin_data_records = {} + + # Inspect the data and check that it has the expected structure and content. + for entry in data: + # Check metadata entry for expected values + if entry.get('metadata', False): + print('Found metadata entry') + found_metadata = True + + expected_apps = ['InvenTree', 'allauth', 'dbbackup', PLUGIN_KEY] + + apps = entry.get('installed_apps', []) + + for app in expected_apps: + if app not in apps: + print(f'- Expected app "{app}" not found in installed apps list') + exit(1) + + found_installed_apps = True + + elif entry.get('model', None) == 'plugin.pluginconfig': + key = entry['fields']['key'] + + if key == PLUGIN_SLUG: + print(f'Found plugin configuration for plugin "{PLUGIN_KEY}"') + found_plugin_config = True + + elif entry.get('model', None) == f'{PLUGIN_KEY}.examplemodel': + key = entry['fields']['key'] + value = entry['fields']['value'] + + plugin_data_records[key] = value + + if not found_metadata: + print('Error: No metadata entry found in exported data') + exit(1) + + if not found_installed_apps: + print( + f'Error: Plugin "{PLUGIN_KEY}" not found in installed apps list in metadata' + ) + exit(1) + + if not found_plugin_config: + print(f'Error: No plugin configuration found for plugin "{PLUGIN_KEY}"') + exit(1) + + # Check the extracted plugin records + expected_keys = ['alpha', 'beta', 'gamma', 'delta'] + + for key in expected_keys: + if key not in plugin_data_records: + print( + f'Error: Expected plugin record with key "{key}" not found in exported data' + ) + exit(1) + + print('All checks passed successfully!') diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 7b1a727718..db8dcd6785 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 with: persist-credentials: false - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2 + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 id: filter with: filters: | @@ -168,13 +168,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@c7c53464625b32c7a7e944ae62b3e17d2b600130 # pin@v3.7.0 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # pin@v4.0.0 - name: Set up Docker Buildx if: github.event_name != 'pull_request' - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # pin@v3.12.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # pin@v4.0.0 - name: Set up cosign if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # pin@v4.0.0 + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # pin@v4.1.2 - name: Check if Dockerhub login is required id: docker_login run: | @@ -185,14 +185,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@c94ce9fb468520275223c153574b00df6fe4bcc9 # pin@v3.7.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # pin@v4.1.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@c94ce9fb468520275223c153574b00df6fe4bcc9 # pin@v3.7.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # pin@v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -201,7 +201,7 @@ jobs: - name: Extract Docker metadata if: github.event_name != 'pull_request' id: meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # pin@v5.10.0 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # pin@v6.0.0 with: images: | inventree/inventree diff --git a/.github/workflows/import_export.yaml b/.github/workflows/import_export.yaml new file mode 100644 index 0000000000..6cf00b0408 --- /dev/null +++ b/.github/workflows/import_export.yaml @@ -0,0 +1,120 @@ +# Ensure that data import / export functionality works as expected. +# - Create a dataset in a Postgres database (including plugin data) +# - Export the dataset to an agnostic format (JSON) +# - Import the dataset into a Sqlite database + +name: Import / Export + +on: + push: + branches-ignore: ["l10*"] + pull_request: + branches-ignore: ["l10*"] + +permissions: + contents: read + +env: + python_version: 3.11 + + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + INVENTREE_DEBUG: false + INVENTREE_LOG_LEVEL: WARNING + 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 + + INVENTREE_PLUGINS_ENABLED: true + INVENTREE_AUTO_UPDATE: true + INVENTREE_PLUGINS_MANDATORY: "dummy-app-plugin" + INVENTREE_GLOBAL_SETTINGS: '{"ENABLE_PLUGINS_APP": true}' + + DATA_FILE: /home/runner/work/InvenTree/test_inventree_data.json + + INVENTREE_DB_ENGINE: postgresql + INVENTREE_DB_NAME: inventree + INVENTREE_DB_USER: inventree + INVENTREE_DB_PASSWORD: password + INVENTREE_DB_HOST: "127.0.0.1" + INVENTREE_DB_PORT: 5432 + +jobs: + + paths-filter: + name: filter + runs-on: ubuntu-latest + outputs: + server: ${{ steps.filter.outputs.server }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + with: + persist-credentials: false + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 + id: filter + with: + filters: | + server: + - .github/workflows/import_export.yaml + - .github/scripts/check_exported_data.py + - 'src/backend/**' + - 'tasks.py' + test: + runs-on: ubuntu-latest + needs: paths-filter + if: needs.paths-filter.outputs.server == 'true' || contains(github.event.pull_request.labels.*.name, 'full-run') + + services: + postgres: + image: postgres:17 + env: + POSTGRES_USER: inventree + POSTGRES_PASSWORD: password + ports: + - 5432:5432 + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + - name: Environment Setup + uses: ./.github/actions/setup + with: + apt-dependency: gettext poppler-utils libpq-dev + pip-dependency: psycopg + update: true + static: false + - name: Setup Postgres Database + run: | + invoke migrate + invoke dev.setup-test -i + - name: Create Plugin Data + run: | + pip install -U inventree-dummy-app-plugin==0.1.0 + invoke migrate + cd src/backend/InvenTree && python manage.py create_dummy_data + - name: Export Postgres Dataset + run: | + invoke export-records -o -f ${{ env.DATA_FILE }} + python .github/scripts/check_exported_data.py ${{ env.DATA_FILE }} + invoke dev.delete-data --force + - name: Update Environment Variables for Sqlite + run: | + echo "Updating environment variables for Sqlite" + echo "INVENTREE_DB_ENGINE=sqlite" >> $GITHUB_ENV + echo "INVENTREE_DB_NAME=/home/runner/work/InvenTree/test_inventree_db.sqlite3" >> $GITHUB_ENV + - name: Setup Sqlite Database + run: | + invoke migrate + test -f /home/runner/work/InvenTree/test_inventree_db.sqlite3 || (echo "Sqlite database not created" && exit 1) + - name: Import Sqlite Dataset + run: | + invoke import-records -c -f ${{ env.DATA_FILE }} --strict + cd src/backend/InvenTree && python manage.py check_dummy_data + - name: Export Sqlite Dataset + run: | + invoke export-records -o -f ${{ env.DATA_FILE }} + python .github/scripts/check_exported_data.py ${{ env.DATA_FILE }} diff --git a/.github/workflows/qc_checks.yaml b/.github/workflows/qc_checks.yaml index 985c0e213d..b877b5aff4 100644 --- a/.github/workflows/qc_checks.yaml +++ b/.github/workflows/qc_checks.yaml @@ -10,7 +10,7 @@ on: env: python_version: 3.11 - node_version: 20 + node_version: 24 # The OS version must be set per job server_start_sleep: 60 @@ -23,8 +23,6 @@ env: INVENTREE_SITE_URL: http://localhost:8000 INVENTREE_DEBUG: true - use_performance: false - permissions: contents: read @@ -42,12 +40,14 @@ jobs: cicd: ${{ steps.filter.outputs.cicd }} requirements: ${{ steps.filter.outputs.requirements }} runner-perf: ${{ steps.runner-perf.outputs.runner }} + performance: ${{ steps.performance.outputs.force-performance }} + submit-performance: ${{ steps.runner-perf.outputs.submit-performance }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 with: persist-credentials: false - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2 + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 id: filter with: filters: | @@ -77,13 +77,32 @@ jobs: if: | contains(github.event.pull_request.labels.*.name, 'dependency') || contains(github.event.pull_request.labels.*.name, 'full-run') + - name: Is performance testing being forced? + run: echo "force-performance=true" >> $GITHUB_OUTPUT + id: performance + if: | + contains(github.event.pull_request.labels.*.name, 'performance-run') - name: Which runner to use? + env: + GITHUB_REF: ${{ github.ref }} + PERFORMANCE: ${{ steps.performance.outputs.force-performance }} id: runner-perf # decide if we are running in inventree/inventree -> use codspeed-macro runner else ubuntu-24.04 - run: echo "runner=$([[ '${{ github.repository }}' == 'inventree/InvenTree' && '${{ env.use_performance }}' == 'true' ]] && echo 'codspeed-macro' || echo 'ubuntu-24.04')" >> $GITHUB_OUTPUT + run: | + is_main_push=false + if [[ '${{ github.event_name }}' == 'push' && "$GITHUB_REF" == 'refs/heads/master' ]]; then + is_main_push=true + fi + if [[ '${{ github.repository }}' == 'inventree/InvenTree' && ( "$is_main_push" == 'true' || "$PERFORMANCE" == 'true' ) ]]; then + echo "runner=codspeed-macro" >> "$GITHUB_OUTPUT" + echo "submit-performance=true" >> "$GITHUB_OUTPUT" + else + echo "runner=ubuntu-24.04" >> "$GITHUB_OUTPUT" + echo "submit-performance=false" >> "$GITHUB_OUTPUT" + fi - pre-commit: - name: Style [pre-commit] + code-style: + name: Style [prek] runs-on: ubuntu-24.04 needs: paths-filter 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' @@ -97,8 +116,8 @@ jobs: with: python-version: ${{ env.python_version }} cache: "pip" - - name: Run pre-commit Checks - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # pin@v3.0.1 + - name: Run pre commit hook Checks + uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # pin@v2 - name: Check Version run: | pip install --require-hashes -r contrib/dev_reqs/requirements.txt @@ -107,7 +126,7 @@ jobs: typecheck: name: Style [Typecheck] runs-on: ubuntu-24.04 - needs: [paths-filter, pre-commit] + needs: [code-style, paths-filter] if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.requirements == 'true' || needs.paths-filter.outputs.force == 'true' steps: @@ -183,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@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: schema.yml path: src/backend/InvenTree/schema.yml @@ -203,7 +222,7 @@ jobs: echo "Downloaded api.yaml" - name: Running OpenAPI Spec diff action id: breaking_changes - uses: oasdiff/oasdiff-action/diff@1c611ffb1253a72924624aa4fb662e302b3565d3 # pin@main + uses: oasdiff/oasdiff-action/diff@6147a58e5d1249a12f42fc864ab791d571a30015 # pin@main with: base: "api.yaml" revision: "src/backend/InvenTree/schema.yml" @@ -232,17 +251,17 @@ jobs: - name: Extract settings / tags run: invoke int.export-definitions --basedir docs - name: Upload settings - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: inventree_settings.json path: docs/generated/inventree_settings.json - name: Upload tags - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: inventree_tags.yml path: docs/generated/inventree_tags.yml - name: Upload filters - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: inventree_filters.yml path: docs/generated/inventree_filters.yml @@ -265,7 +284,7 @@ jobs: - name: Create artifact directory run: mkdir -p artifact - name: Download schema artifact - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # pin@v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # pin@v8.0.1 with: path: artifact merge-multiple: true @@ -291,8 +310,8 @@ jobs: name: Tests - inventree-python runs-on: ${{ needs.paths-filter.outputs.runner-perf }} - needs: ["pre-commit", "paths-filter"] - if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true' + needs: ["code-style", "paths-filter"] + if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true' || needs.paths-filter.outputs.performance == 'true' permissions: contents: read id-token: write @@ -310,7 +329,7 @@ jobs: INVENTREE_SITE_URL: http://127.0.0.1:12345 INVENTREE_DEBUG: true INVENTREE_LOG_LEVEL: WARNING - node_version: '>=20.19.6' + node_version: '>=24' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 @@ -322,6 +341,7 @@ jobs: apt-dependency: gettext poppler-utils dev-install: true update: true + static: true npm: true - name: Download Python Code For `${WRAPPER_NAME}` run: git clone --depth 1 https://github.com/inventree/${WRAPPER_NAME} ./${WRAPPER_NAME} @@ -341,10 +361,11 @@ jobs: pip uninstall pytest-django -y cd ${WRAPPER_NAME} pip install . + if: needs.paths-filter.outputs.submit-performance == 'true' - name: Performance Reporting - uses: CodSpeedHQ/action@dbda7111f8ac363564b0c51b992d4ce76bb89f2f # pin@v4 + uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # pin@v4.15.1 # check if we are in inventree/inventree - reporting only works in that OIDC context - if: github.repository == 'inventree/InvenTree' + if: github.repository == 'inventree/InvenTree' && needs.paths-filter.outputs.submit-performance == 'true' with: mode: walltime run: pytest ./src/performance --codspeed @@ -353,7 +374,7 @@ jobs: name: Tests - DB [SQLite] + Coverage ${{ matrix.python_version }} runs-on: ubuntu-24.04 - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true' continue-on-error: true # continue if a step fails so that coverage gets pushed strategy: @@ -378,6 +399,7 @@ jobs: apt-dependency: gettext poppler-utils dev-install: true update: true + static: true - name: Data Export Test uses: ./.github/actions/migration - name: Test Translations @@ -387,13 +409,13 @@ jobs: - name: Coverage Tests run: invoke dev.test --check --coverage --translations - name: Upload raw coverage to artifacts - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: coverage path: .coverage retention-days: 14 - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # pin@v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -404,9 +426,9 @@ jobs: name: Tests - Performance runs-on: ${{ needs.paths-filter.outputs.runner-perf }} - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] # check if we are in inventree/inventree - reporting only works in that OIDC context - if: (needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true') && github.repository == 'inventree/InvenTree' + if: (needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true') && github.repository == 'inventree/InvenTree' && needs.paths-filter.outputs.submit-performance == 'true' permissions: contents: read id-token: write @@ -430,9 +452,9 @@ jobs: update: true npm: true env: - node_version: '>=20.19.0' + node_version: '>=24' - name: Performance Reporting - uses: CodSpeedHQ/action@dbda7111f8ac363564b0c51b992d4ce76bb89f2f # pin@v4 + uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # pin@v4.15.1 with: mode: walltime run: inv dev.test --pytest @@ -440,7 +462,7 @@ jobs: postgres: name: Tests - DB [PostgreSQL] runs-on: ubuntu-24.04 - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true' env: @@ -480,6 +502,7 @@ jobs: pip-dependency: psycopg django-redis>=5.0.0 dev-install: true update: true + static: true - name: Run Tests run: invoke dev.test --check --translations - name: Data Export Test @@ -489,7 +512,7 @@ jobs: name: Tests - DB [MySQL] runs-on: ubuntu-24.04 - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.force == 'true' env: @@ -528,6 +551,7 @@ jobs: pip-dependency: mysqlclient dev-install: true update: true + static: true - name: Run Tests run: invoke dev.test --check --translations - name: Data Export Test @@ -573,7 +597,7 @@ jobs: - name: Run Tests run: invoke dev.test --check --migrations --report --coverage --translations - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # pin@v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -644,7 +668,7 @@ jobs: name: Tests - Web UI runs-on: ubuntu-24.04 timeout-minutes: 60 - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] if: needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.force == 'true' services: postgres: @@ -682,7 +706,7 @@ jobs: npm: true install: true update: true - apt-dependency: postgresql-client libpq-dev + apt-dependency: gettext postgresql-client libpq-dev pip-dependency: psycopg2 - name: Set up test data run: | @@ -701,7 +725,7 @@ jobs: 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@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 if: ${{ !cancelled() && steps.tests.outcome == 'failure' }} with: name: playwright-report @@ -710,7 +734,7 @@ jobs: - 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@671740ac38dd9b0130fbe1cec585b89eea48d3de # pin@v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} slug: inventree/InvenTree @@ -739,14 +763,14 @@ jobs: - name: Install dependencies run: cd src/frontend && yarn install - name: Build frontend - run: cd src/frontend && yarn run compile && yarn run build + 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@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: frontend-build path: src/backend/InvenTree/web/static/web @@ -755,7 +779,7 @@ jobs: zizmor: name: Security [Zizmor] runs-on: ubuntu-24.04 - needs: ["pre-commit", "paths-filter"] + needs: ["code-style", "paths-filter"] if: needs.paths-filter.outputs.cicd == 'true' || needs.paths-filter.outputs.force == 'true' permissions: @@ -765,13 +789,5 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 with: persist-credentials: false - - uses: hynek/setup-cached-uv@757bedc3f972eb7227a1aa657651f15a8527c817 # pin@v2 - - name: Run zizmor - run: uvx zizmor --format sarif . > results.sarif - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # pin@v3 - with: - sarif_file: results.sarif - category: zizmor + - name: Run zizmor 🌈 + uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bd1cdf8242..9cdf67065d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -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@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa # pin@v1.0.0 + uses: ad-m/github-push-action@4cc74773234f74829a8c21bc4d69dd4be9cfa599 # pin@v1.1.0 if: env.stable_release == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -55,7 +55,7 @@ jobs: - name: Build frontend run: cd src/frontend && npm run compile && npm run build - name: Create SBOM for frontend - uses: anchore/sbom-action@28d71544de8eaf1b958d335707167c5f783590ad # pin@v0 + uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # pin@v0 with: artifact-name: frontend-build.spdx path: src/frontend @@ -73,31 +73,26 @@ jobs: zip -r ../frontend-build.zip * .vite - name: Attest Build Provenance id: attest - uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # pin@v1 + uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # pin@v1 with: subject-path: "${{ github.workspace }}/src/backend/InvenTree/web/static/frontend-build.zip" - name: Upload frontend - uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: src/backend/InvenTree/web/static/frontend-build.zip - asset_name: frontend-build.zip - tag: ${{ github.ref }} - overwrite: true + run: gh release upload ${REF} src/backend/InvenTree/web/static/frontend-build.zip#frontend-build.zip + env: + REF: ${{ github.ref_name }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload frontend to artifacts - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 with: name: frontend-build path: src/backend/InvenTree/web/static/frontend-build.zip - name: Upload Attestation - uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - asset_name: frontend-build.intoto.jsonl - file: ${{ steps.attest.outputs.bundle-path}} - tag: ${{ github.ref }} - overwrite: true + run: gh release upload ${REF} ${BUNDLE_PATH}#frontend-build.intoto.jsonl + env: + REF: ${{ github.ref_name }} + BUNDLE_PATH: ${{ steps.attest.outputs.bundle-path}} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} docs: runs-on: ubuntu-24.04 @@ -134,13 +129,10 @@ jobs: cd docs/site zip -r docs-html.zip * - name: Publish documentation - uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: docs/site/docs-html.zip - asset_name: docs-html.zip - tag: ${{ github.ref }} - overwrite: true + run: gh release upload ${REF} docs/site/docs-html.zip#docs-html.zip + env: + REF: ${{ github.ref_name }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} build-pkgr: if: github.repository == 'inventree/InvenTree' @@ -163,7 +155,7 @@ jobs: persist-credentials: false - name: Get frontend artifact - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # pin@v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # pin@v8.0.1 with: name: frontend-build - name: Setup @@ -244,10 +236,9 @@ jobs: channel: ${{ env.pkg_channel }} file: ${{ steps.package.outputs.package_path }} - name: Publish to artifact - uses: svenstaro/upload-release-action@6b7fa9f267e90b50a19fef07b3596790bb941741 # pin@2.11.3 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ${{ steps.package.outputs.package_path }} - asset_name: ${{ matrix.target }}-{{ steps.setup.outputs.version }}.tar.gz - tag: ${{ github.ref }} - overwrite: true + run: gh release upload ${REF} ${PACKAGE_PATH}#${PACKAGE_NAME} + env: + REF: ${{ github.ref_name }} + PACKAGE_PATH: ${{ steps.package.outputs.package_path }} + PACKAGE_NAME: ${{ matrix.target }}-{{ steps.setup.outputs.version }}.tar.gz + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 9b779ce73a..4d2d571f31 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: SARIF file path: results.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@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: results.sarif diff --git a/.github/workflows/translations.yaml b/.github/workflows/translations.yaml index e743100701..d619040b90 100644 --- a/.github/workflows/translations.yaml +++ b/.github/workflows/translations.yaml @@ -7,7 +7,7 @@ on: env: python_version: 3.11 - node_version: 20 + node_version: 24 permissions: contents: read @@ -56,7 +56,7 @@ jobs: echo "Resetting to HEAD~" git reset HEAD~ || true - name: crowdin action - uses: crowdin/github-action@b4b468cffefb50bdd99dd83e5d2eaeb63c880380 # pin@v2 + uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # pin@v2 with: upload_sources: true upload_translations: false diff --git a/.pkgr.yml b/.pkgr.yml index 01326874d2..ac9dc06408 100644 --- a/.pkgr.yml +++ b/.pkgr.yml @@ -20,6 +20,7 @@ before: - contrib/packager.io/before.sh 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" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4d6e46287..b140056f45 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: exclude: mkdocs.yml - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.1 + rev: v0.15.12 hooks: - id: ruff-format args: [--preview] @@ -29,7 +29,7 @@ repos: --preview ] - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.10.2 + rev: 0.11.12 hooks: - id: pip-compile name: pip-compile requirements-dev.in @@ -48,15 +48,15 @@ repos: args: [src/backend/requirements.in, -o, src/backend/requirements-3.14.txt, --python-version=3.14, -c, src/backend/requirements.txt] files: src/backend/requirements\.(in|txt)$ - id: pip-compile - name: pip-compile requirements.txt + name: pip-compile contrib/dev_reqs/requirements.txt args: [contrib/dev_reqs/requirements.in, -o, contrib/dev_reqs/requirements.txt, -c, src/backend/requirements.txt] files: contrib/dev_reqs/requirements\.(in|txt)$ - id: pip-compile - name: pip-compile requirements.txt + name: pip-compile docs/requirements.txt args: [docs/requirements.in, -o, docs/requirements.txt, -c, src/backend/requirements.txt] files: docs/requirements\.(in|txt)$ - id: pip-compile - name: pip-compile requirements.txt + name: pip-compile contrib/container/requirements.txt args: [contrib/container/requirements.in, -o, contrib/container/requirements.txt, --python-version=3.14, -c, src/backend/requirements.txt] files: contrib/container/requirements\.(in|txt)$ - repo: https://github.com/Riverside-Healthcare/djLint @@ -64,7 +64,7 @@ repos: hooks: - id: djlint-django - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.4.2 hooks: - id: codespell additional_dependencies: @@ -79,13 +79,13 @@ repos: src/frontend/vite.config.ts | )$ - repo: https://github.com/biomejs/pre-commit - rev: v2.3.15 + rev: v2.4.14 hooks: - id: biome-check additional_dependencies: ["@biomejs/biome@1.9.4"] files: ^src/frontend/.*\.(js|ts|tsx)$ - repo: https://github.com/gitleaks/gitleaks - rev: v8.30.0 + rev: v8.30.1 hooks: - id: gitleaks language_version: 1.25.4 @@ -97,3 +97,4 @@ repos: rev: 0.4.3 hooks: - id: teyit + language_version: python3.11 diff --git a/.vscode/launch.json b/.vscode/launch.json index e32e7beeb8..17186b6d37 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -36,7 +36,9 @@ "program": "${workspaceFolder}/src/backend/InvenTree/manage.py", "args": [ "runserver", - "0.0.0.0:8000" + "0.0.0.0:8000", + // "--sync",// Synchronize worker tasks to foreground thread + // "--noreload", // disable auto-reload ], "django": true, "justMyCode": false diff --git a/CHANGELOG.md b/CHANGELOG.md index c70ced72de..6242bb4037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,20 +19,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking Changes -- [#11303](https://github.com/inventree/InvenTree/pull/11303) removes the `default_supplier` field from the `Part` model. Instead, the `SupplierPart` model now has a `primary` field which is used to indicate which supplier is the default for a given part. Any external client applications which made use of the old `default_supplier` field will need to be updated. +- [#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 ### Added +- [#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. +- [#11872](https://github.com/inventree/InvenTree/pull/11872) adds a global setting to allow or disallow the deletion of serialized stock items. +- [#11861](https://github.com/inventree/InvenTree/pull/11861) adds support for bulk-replacing a component in multiple BOMs simultaneously +- [#11853](https://github.com/inventree/InvenTree/pull/11853) adds BOM comparison functionality, allowing users to compare the BOM of one assembly with another assembly. +- [#11809](https://github.com/inventree/InvenTree/pull/11809) adds multi-level subassembly display mode to the BOM table, allowing users to view multiple levels of subassemblies in a single table view. This is an optional display mode which can be toggled on or off by the user. +- [#11778](https://github.com/inventree/InvenTree/pull/11778) adds inline supplier part creation to po line item addition dialog. +- [#11772](https://github.com/inventree/InvenTree/pull/11772) the UI now warns if you navigate away from a note panel with unsaved changes +- [#11788](https://github.com/inventree/InvenTree/pull/11788) adds support for custom permissions checks on database models defined in plugins. If a model defines a `check_user_permission` classmethod, this will be called to determine if a user has permission to view the model. This is required for plugin models which do not have the required ruleset definitions for the standard permission system. +- [#9570](https://github.com/inventree/InvenTree/pull/9570) adds support for defining primary actions via plugins + +### Changed + +- [#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 + +- [#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 + +### Breaking Changes + +- [#11303](https://github.com/inventree/InvenTree/pull/11303) removes the `default_supplier` field from the `Part` model. Instead, the `SupplierPart` model now has a `primary` field which is used to indicate which supplier is the default for a given part. Any external client applications which made use of the old `default_supplier` field will need to be updated. +- [#11500](https://github.com/inventree/InvenTree/pull/11500) fixes a spelling mistake in the database configuration values, which may affect some users running the PostgreSQL database backend. The `tcp_keepalives_internal` option has been renamed to `tcp_keepalives_interval` to reflect the correct PostgreSQL configuration option name. If you are using PostgreSQL, and have set a custom value for the `tcp_keepalives_internal` option, you will need to update this to `tcp_keepalives_interval` in your configuration (either via environment variable or config file). + +### Added + +- [#11702](https://github.com/inventree/InvenTree/pull/11702) adds "last updated" and "updated by" fields for label and report templates, allowing users to track when a template was last modified and by whom. +- [#11685](https://github.com/inventree/InvenTree/pull/11685) exposes the data importer wizard to the plugin interface, allowing plugins to trigger the data importer wizard and perform custom data imports from the UI. +- [#11692](https://github.com/inventree/InvenTree/pull/11692) adds line item numbering for external orders (purchase, sales and return orders). This allows users to specify a line number for each line item on the order, which can be used for reference purposes. The line number is optional, and can be left blank if not required. The line number is stored as a string, to allow for more flexible formatting (e.g. "1", "1.1", "A", etc). +- [#11641](https://github.com/inventree/InvenTree/pull/11641) adds support for custom parameters against the SalesOrderShipment model. +- [#11527](https://github.com/inventree/InvenTree/pull/11527) adds a new API endpoint for monitoring the status of a particular background task. This endpoint allows clients to check the status of a background task and receive updates when the task is complete. This is useful for long-running tasks that may take some time to complete, allowing clients to provide feedback to users about the progress of the task. - [#11405](https://github.com/inventree/InvenTree/pull/11405) adds default table filters, which hide inactive items by default. The default table filters are overridden by user filter selection, and only apply to the table view initially presented to the user. This means that users can still view inactive items if they choose to, but they will not be shown by default. - [#11222](https://github.com/inventree/InvenTree/pull/11222) adds support for data import using natural keys, allowing for easier association of related objects without needing to know their internal database IDs. - [#11383](https://github.com/inventree/InvenTree/pull/11383) adds "exists_for_model_id", "exists_for_related_model", and "exists_for_related_model_id" filters to the ParameterTemplate API endpoint. These filters allow users to check for the existence of parameters associated with specific models or related models, improving the flexibility and usability of the API. - [#10887](https://github.com/inventree/InvenTree/pull/10887) adds the ability to auto-allocate tracked items against specific build outputs. Currently, this will only allocate items where the serial number of the tracked item matches the serial number of the build output, but in future this may be extended to allow for more flexible allocation rules. - [#11372](https://github.com/inventree/InvenTree/pull/11372) adds backup metadata setter and restore metadata validator functions to ensure common footguns are harder to trigger when using the backup and restore functionality. +- [#11374](https://github.com/inventree/InvenTree/pull/11374) adds `updated_at` field on purchase, sales and return orders. +- [#11074](https://github.com/inventree/InvenTree/pull/11074) adds "Keep form open" option on create form which leaves dialog with form opened after form submitting. ### Changed +- [#11648](https://github.com/inventree/InvenTree/pull/11648) improves the import/export process, allowing data records defined by plugins to be loaded when importing a database from a file. +- [#11630](https://github.com/inventree/InvenTree/pull/11630) enhances the `import_records` and `export_records` system commands, by adding a metadata entry to the exported data file to allow for compatibility checks during data import. + ### Removed +- [#11581](https://github.com/inventree/InvenTree/pull/11581) removes the ability to specify arbitrary filters when performing bulk operations via the API. This functionality represented a significant security risk, and was not required for any existing use cases. Bulk operations now only work with a provided list of primary keys. + ## 1.2.0 - 2026-02-12 ### Breaking Changes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7c62407f07..c589902e9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,6 @@ InvenTree/ ├─ CONTRIBUTING.md # Contribution guidelines and overview ├─ Procfile # Process definition for Debian/Ubuntu packages ├─ README.md # General project information and overview -├─ runtime.txt # Python runtime settings for Debian/Ubuntu packages build ├─ SECURITY.md # Project security policy ├─ tasks.py # Action definitions for development, testing and deployment ``` diff --git a/README.md b/README.md index 792e6e267c..7803cf8ec5 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ InvenTree is designed to be **extensible**, and provides multiple options for ** diff --git a/codecov.yml b/codecov.yml index b06601b57b..b49179c3ed 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,6 @@ +ignore: + - "src/backend/InvenTree/**/test_migrations.py" + coverage: status: project: diff --git a/contrib/container/Dockerfile b/contrib/container/Dockerfile index b7ee19c4f6..2a8693f11d 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-02-23 -FROM python:3.14-slim-trixie@sha256:486b8092bfb12997e10d4920897213a06563449c951c5506c2a2cfaf591c599f AS inventree_base +# Base image last bumped 2026-03-20 +FROM python:3.14-slim-trixie@sha256:fb83750094b46fd6b8adaa80f66e2302ecbe45d513f6cece637a841e1025b4ca AS inventree_base # Build arguments for this image ARG commit_tag="" diff --git a/contrib/container/requirements.txt b/contrib/container/requirements.txt index ccf76c5555..6e0559a9c2 100644 --- a/contrib/container/requirements.txt +++ b/contrib/container/requirements.txt @@ -6,9 +6,9 @@ asgiref==3.11.1 \ # via # -c src/backend/requirements.txt # django -django==5.2.11 \ - --hash=sha256:7f2d292ad8b9ee35e405d965fbbad293758b858c34bbf7f3df551aeeac6f02d3 \ - --hash=sha256:e7130df33ada9ab5e5e929bc19346a20fe383f5454acb2cc004508f242ee92c0 +django==5.2.14 \ + --hash=sha256:58a63ba841662e5c686b57ba1fec52ddd68c0b93bd96ac3029d55728f00bf8a2 \ + --hash=sha256:6f712143bd3064310d1f50fac859c3e9a274bdcfc9595339853be7779297fc76 # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in @@ -17,15 +17,15 @@ django-auth-ldap==5.3.0 \ --hash=sha256:743d8107b146240b46f7e97207dc06cb11facc0cd70dce490b7ca09dd5643d19 \ --hash=sha256:aa880415983149b072f876d976ef8ec755a438090e176817998263a6ed9e1038 # via -r contrib/container/requirements.in -gunicorn==25.1.0 \ - --hash=sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616 \ - --hash=sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b +gunicorn==25.3.0 \ + --hash=sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660 \ + --hash=sha256:f74e1b2f9f76f6cd1ca01198968bd2dd65830edc24b6e8e4d78de8320e2fe889 # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in -invoke==2.2.1 \ - --hash=sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 \ - --hash=sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707 +invoke==3.0.3 \ + --hash=sha256:437b6a622223824380bfb4e64f612711a6b648c795f565efc8625af66fb57f0c \ + --hash=sha256:f11327165e5cbb89b2ad1d88d3292b5113332c43b8553b494da435d6ec6f5053 # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in @@ -44,92 +44,91 @@ mariadb==1.1.14 \ --hash=sha256:98d552a8bb599eceaa88f65002ad00bd88aeed160592c273a7e5c1d79ab733dd \ --hash=sha256:e6d702a53eccf20922e47f2f45cfb5c7a0c2c6c0a46e4ee2d8a80d0ff4a52f34 # via -r contrib/container/requirements.in -mysqlclient==2.2.7 \ - --hash=sha256:199dab53a224357dd0cb4d78ca0e54018f9cee9bf9ec68d72db50e0a23569076 \ - --hash=sha256:201a6faa301011dd07bca6b651fe5aaa546d7c9a5426835a06c3172e1056a3c5 \ - --hash=sha256:24ae22b59416d5fcce7e99c9d37548350b4565baac82f95e149cac6ce4163845 \ - --hash=sha256:2e3c11f7625029d7276ca506f8960a7fd3c5a0a0122c9e7404e6a8fe961b3d22 \ - --hash=sha256:4b4c0200890837fc64014cc938ef2273252ab544c1b12a6c1d674c23943f3f2e \ - --hash=sha256:92af368ed9c9144737af569c86d3b6c74a012a6f6b792eb868384787b52bb585 \ - --hash=sha256:977e35244fe6ef44124e9a1c2d1554728a7b76695598e4b92b37dc2130503069 \ - --hash=sha256:a22d99d26baf4af68ebef430e3131bb5a9b722b79a9fcfac6d9bbf8a88800687 +mysqlclient==2.2.8 \ + --hash=sha256:000c7ec3d11e7c411db832e4cfcd7f05db47464326381f5d5ae991b4bb572f93 \ + --hash=sha256:260cce0e81446c83bf0a389e0fae38d68547d9f8fc0833bc733014e10ce28a99 \ + --hash=sha256:60c9ed339dc09e3d5380cc2a9f42e86754fee25a661ced77a02df77990664c92 \ + --hash=sha256:86db31bba7b3480fec2751350e9790e24f016f89af33a87bab7e79f7196474e8 \ + --hash=sha256:8ed20c5615a915da451bb308c7d0306648a4fd9a2809ba95c992690006306199 \ + --hash=sha256:9bed7c8d3b629bdc09e17fb628d5b3b0a5fd1f12b09432b464b9126c727bedc0 \ + --hash=sha256:a81f5e12f8d05439709cb02fba97f9f76d1a6c528164f2260d8798fec969e300 # via -r contrib/container/requirements.in -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # -c src/backend/requirements.txt # gunicorn # mariadb # wheel -psycopg[binary, pool]==3.3.2 \ - --hash=sha256:3e94bc5f4690247d734599af56e51bae8e0db8e4311ea413f801fef82b14a99b \ - --hash=sha256:707a67975ee214d200511177a6a80e56e654754c9afca06a7194ea6bbfde9ca7 +psycopg[binary, pool]==3.3.3 \ + --hash=sha256:5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9 \ + --hash=sha256:f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698 # via -r contrib/container/requirements.in -psycopg-binary==3.3.2 \ - --hash=sha256:03b7cd73fb8c45d272a34ae7249713e32492891492681e3cf11dff9531cf37e9 \ - --hash=sha256:04bb2de4ba69d6f8395b446ede795e8884c040ec71d01dd07ac2b2d18d4153d1 \ - --hash=sha256:0611f4822674f3269e507a307236efb62ae5a828fcfc923ac85fe22ca19fd7c8 \ - --hash=sha256:0768c5f32934bb52a5df098317eca9bdcf411de627c5dca2ee57662b64b54b41 \ - --hash=sha256:07a5f030e0902ec3e27d0506ceb01238c0aecbc73ecd7fa0ee55f86134600b5b \ - --hash=sha256:083c2e182be433f290dc2c516fd72b9b47054fcd305cce791e0a50d9e93e06f2 \ - --hash=sha256:09b3014013f05cd89828640d3a1db5f829cc24ad8fa81b6e42b2c04685a0c9d4 \ - --hash=sha256:0ae60e910531cfcc364a8f615a7941cac89efeb3f0fffe0c4824a6d11461eef7 \ - --hash=sha256:136c43f185244893a527540307167f5d3ef4e08786508afe45d6f146228f5aa9 \ - --hash=sha256:1586e220be05547c77afc326741dd41cc7fba38a81f9931f616ae98865439678 \ - --hash=sha256:1e09d0d93d35c134704a2cb2b15f81ffc8174fd602f3e08f7b1a3d8896156cf0 \ - --hash=sha256:1ea41c0229f3f5a3844ad0857a83a9f869aa7b840448fa0c200e6bcf85d33d19 \ - --hash=sha256:23d2594af848c1fd3d874a9364bef50730124e72df7bb145a20cb45e728c50ed \ - --hash=sha256:3789d452a9d17a841c7f4f97bbcba51a21f957ea35641a4c98507520e6b6a068 \ - --hash=sha256:3ff7489df5e06c12d1829544eaec64970fe27fe300f7cf04c8495fe682064688 \ - --hash=sha256:43b130e3b6edcb5ee856c7167ccb8561b473308c870ed83978ae478613764f1c \ - --hash=sha256:44e89938d36acc4495735af70a886d206a5bfdc80258f95b69b52f68b2968d9e \ - --hash=sha256:458696a5fa5dad5b6fb5d5862c22454434ce4fe1cf66ca6c0de5f904cbc1ae3e \ - --hash=sha256:50ff10ab8c0abdb5a5451b9315538865b50ba64c907742a1385fdf5f5772b73e \ - --hash=sha256:522b79c7db547767ca923e441c19b97a2157f2f494272a119c854bba4804e186 \ - --hash=sha256:59d0163c4617a2c577cb34afbed93d7a45b8c8364e54b2bd2020ff25d5f5f860 \ - --hash=sha256:5a327327f1188b3fbecac41bf1973a60b86b2eb237db10dc945bd3dc97ec39e4 \ - --hash=sha256:649c1d33bedda431e0c1df646985fbbeb9274afa964e1aef4be053c0f23a2924 \ - --hash=sha256:716a586f99bbe4f710dc58b40069fcb33c7627e95cc6fc936f73c9235e07f9cf \ - --hash=sha256:742ce48cde825b8e52fb1a658253d6d1ff66d152081cbc76aa45e2986534858d \ - --hash=sha256:74bc306c4b4df35b09bc8cecf806b271e1c5d708f7900145e4e54a2e5dedfed0 \ - --hash=sha256:7c1feba5a8c617922321aef945865334e468337b8fc5c73074f5e63143013b5a \ - --hash=sha256:7c43a773dd1a481dbb2fe64576aa303d80f328cce0eae5e3e4894947c41d1da7 \ - --hash=sha256:8309ee4569dced5e81df5aa2dcd48c7340c8dee603a66430f042dfbd2878edca \ - --hash=sha256:8db9034cde3bcdafc66980f0130813f5c5d19e74b3f2a19fb3cfbc25ad113121 \ - --hash=sha256:8ea05b499278790a8fa0ff9854ab0de2542aca02d661ddff94e830df971ff640 \ - --hash=sha256:90ed9da805e52985b0202aed4f352842c907c6b4fc6c7c109c6e646c32e2f43b \ - --hash=sha256:94503b79f7da0b65c80d0dbb2f81dd78b300319ec2435d5e6dcf9622160bc2fa \ - --hash=sha256:9742580ecc8e1ac45164e98d32ca6df90da509c2d3ff26be245d94c430f92db4 \ - --hash=sha256:9ca24062cd9b2270e4d77576042e9cc2b1d543f09da5aba1f1a3d016cea28390 \ - --hash=sha256:a9387ab615f929e71ef0f4a8a51e986fa06236ccfa9f3ec98a88f60fbf230634 \ - --hash=sha256:ac230e3643d1c436a2dfb59ca84357dfc6862c9f372fc5dbd96bafecae581f9f \ - --hash=sha256:c3a9ccdfee4ae59cf9bf1822777e763bc097ed208f4901e21537fca1070e1391 \ - --hash=sha256:c5774272f754605059521ff037a86e680342e3847498b0aa86b0f3560c70963c \ - --hash=sha256:c6464150e25b68ae3cb04c4e57496ea11ebfaae4d98126aea2f4702dd43e3c12 \ - --hash=sha256:c749770da0947bc972e512f35366dd4950c0e34afad89e60b9787a37e97cb443 \ - --hash=sha256:cabb2a554d9a0a6bf84037d86ca91782f087dfff2a61298d0b00c19c0bc43f6d \ - --hash=sha256:d391b70c9cc23f6e1142729772a011f364199d2c5ddc0d596f5f43316fbf982d \ - --hash=sha256:d45acedcaa58619355f18e0f42af542fcad3fd84ace4b8355d3a5dea23318578 \ - --hash=sha256:d79b0093f0fbf7a962d6a46ae292dc056c65d16a8ee9361f3cfbafd4c197ab14 \ - --hash=sha256:d88f32ff8c47cb7f4e7e7a9d1747dcee6f3baa19ed9afa9e5694fd2fb32b61ed \ - --hash=sha256:d8c899a540f6c7585cee53cddc929dd4d2db90fd828e37f5d4017b63acbc1a5d \ - --hash=sha256:de9173f8cc0efd88ac2a89b3b6c287a9a0011cdc2f53b2a12c28d6fd55f9f81c \ - --hash=sha256:df65174c7cf6b05ea273ce955927d3270b3a6e27b0b12762b009ce6082b8d3fc \ - --hash=sha256:e22bf6b54df994aff37ab52695d635f1ef73155e781eee1f5fa75bc08b58c8da \ - --hash=sha256:e750afe74e6c17b2c7046d2c3e3173b5a3f6080084671c8aa327215323df155b \ - --hash=sha256:ea4fe6b4ead3bbbe27244ea224fcd1f53cb119afc38b71a2f3ce570149a03e30 \ - --hash=sha256:f26f113013c4dcfbfe9ced57b5bad2035dda1a7349f64bf726021968f9bccad3 \ - --hash=sha256:f3f601f32244a677c7b029ec39412db2772ad04a28bc2cbb4b1f0931ed0ffad7 \ - --hash=sha256:fc5a189e89cbfff174588665bb18d28d2d0428366cc9dae5864afcaa2e57380b +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 # via psycopg psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # via psycopg -pyasn1==0.6.2 \ - --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ - --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b +pyasn1==0.6.3 \ + --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ + --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde # via # pyasn1-modules # python-ldap @@ -219,9 +218,9 @@ pyyaml==6.0.3 \ # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in -setuptools==82.0.0 \ - --hash=sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb \ - --hash=sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0 +setuptools==82.0.1 \ + --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ + --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in @@ -237,28 +236,28 @@ typing-extensions==4.15.0 \ # via # -c src/backend/requirements.txt # psycopg-pool -uv==0.9.22 \ - --hash=sha256:012bdc5285a9cdb091ac514b7eb8a707e3b649af5355fe4afb4920bfe1958c00 \ - --hash=sha256:0cdc653fb601aa7f273242823fa93024f5fd319c66cdf22f36d784858493564c \ - --hash=sha256:0d8f007616cac5962620252b56a1d8224e9b2de566e78558efe04cc18526d507 \ - --hash=sha256:1f45e1e0f26dd47fa01eb421c54cfd39de10fd52ac0a9d7ae45b92fce7d92b0b \ - --hash=sha256:1f979c9d313b4616d9865859ef520bea5df0d4f15c57214589f5676fafa440c1 \ - --hash=sha256:2a4155cf7d0231d0adae94257ee10d70c57c2f592207536ddd55d924590a8c15 \ - --hash=sha256:3422b093b8e6e8de31261133b420c34dbef81f3fd1d82f787ac771b00b54adf8 \ - --hash=sha256:369b55341c6236f42d8fc335876308e5c57c921850975b3019cc9f7ebbe31567 \ - --hash=sha256:3b2bcce464186f8fafa3bf2aa5d82db4e3229366345399cc3f5bcafd616b8fe0 \ - --hash=sha256:41c73a4938818ede30e601cd0be87953e5c6a83dc4762e04e626f2eb9b240ebe \ - --hash=sha256:59c4f6b3659a68c26c50865432a7134386f607432160aad51e2247f862902697 \ - --hash=sha256:77ec4c101d41d7738226466191a7d62f9fa4de06ea580e0801da2f5cd5fa08aa \ - --hash=sha256:8f73043ade8ff6335e19fe1f4e7425d5e28aec9cafd72d13d5b40bb1cbb85690 \ - --hash=sha256:9c238525272506845fe07c0b9088c5e33fcd738e1f49ef49dc3c8112096d2e3a \ - --hash=sha256:b1985559b38663642658069e8d09fa6c30ed1c67654b7e5765240d9e4e9cdd57 \ - --hash=sha256:b78f2605d65c4925631d891dec99b677b05f50c774dedc6ef8968039a5bcfdb0 \ - --hash=sha256:b807bafe6b65fc1fe9c65ffd0d4228db894872de96e7200c44943f24beb68931 \ - --hash=sha256:d9d4be990bb92a68781f7c98d2321b528667b61d565c02ba978488c0210aa768 \ - --hash=sha256:e4b61a9c8b8dcbf64e642d2052342d36a46886b8bc3ccc407282962b970101af +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 # via -r contrib/container/requirements.in -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via -r contrib/container/requirements.in diff --git a/contrib/dev_reqs/requirements.in b/contrib/dev_reqs/requirements.in index d91d3c7581..c148de0a40 100644 --- a/contrib/dev_reqs/requirements.in +++ b/contrib/dev_reqs/requirements.in @@ -1,4 +1,4 @@ # Packages needed for CI/packages -requests==2.32.5 +requests==2.33.1 pyyaml==6.0.3 jc==1.25.6 diff --git a/contrib/dev_reqs/requirements.txt b/contrib/dev_reqs/requirements.txt index 73d6c609ec..0591b6d8a6 100644 --- a/contrib/dev_reqs/requirements.txt +++ b/contrib/dev_reqs/requirements.txt @@ -1,131 +1,147 @@ # 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.1.4 \ - --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ - --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # -c src/backend/requirements.txt # requests -charset-normalizer==3.4.4 \ - --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ - --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ - --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ - --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ - --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ - --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ - --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ - --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ - --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ - --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ - --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ - --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ - --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ - --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ - --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ - --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ - --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ - --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ - --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ - --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ - --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ - --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ - --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ - --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ - --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ - --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ - --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ - --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ - --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ - --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ - --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ - --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ - --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ - --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ - --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ - --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ - --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ - --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ - --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ - --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ - --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ - --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ - --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ - --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ - --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ - --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ - --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ - --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ - --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ - --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ - --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ - --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ - --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ - --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ - --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ - --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ - --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ - --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ - --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ - --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ - --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ - --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ - --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ - --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ - --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ - --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ - --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ - --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ - --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ - --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ - --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ - --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ - --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ - --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ - --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ - --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ - --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ - --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ - --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ - --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ - --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ - --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ - --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ - --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ - --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ - --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ - --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ - --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ - --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ - --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ - --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ - --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ - --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ - --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ - --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ - --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ - --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ - --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ - --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ - --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ - --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ - --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ - --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ - --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ - --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ - --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ - --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ - --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ - --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ - --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ - --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ - --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ - --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 +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 # via # -c src/backend/requirements.txt # requests -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.15 \ + --hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \ + --hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc # via # -c src/backend/requirements.txt # requests @@ -133,9 +149,9 @@ jc==1.25.6 \ --hash=sha256:27f58befc7ae0a4c63322926c5f1ec892e3eac4a065eff3b07cfe420a6924a07 \ --hash=sha256:7367b59e6e0da8babeede1e5b0da083f3c5aa6b6e585b4aed28dd7c4b2d76162 # via -r contrib/dev_reqs/requirements.in -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via jc pyyaml==6.0.3 \ --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ @@ -214,9 +230,9 @@ pyyaml==6.0.3 \ # via # -c src/backend/requirements.txt # -r contrib/dev_reqs/requirements.in -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf +requests==2.33.1 \ + --hash=sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517 \ + --hash=sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # via # -c src/backend/requirements.txt # -r contrib/dev_reqs/requirements.in @@ -224,13 +240,13 @@ ruamel-yaml==0.19.1 \ --hash=sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93 \ --hash=sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993 # via jc -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # -c src/backend/requirements.txt # requests -xmltodict==1.0.2 \ - --hash=sha256:54306780b7c2175a3967cad1db92f218207e5bc1aba697d887807c0fb68b7649 \ - --hash=sha256:62d0fddb0dcbc9f642745d8bbf4d81fd17d6dfaec5a15b5c1876300aad92af0d +xmltodict==1.0.4 \ + --hash=sha256:6d94c9f834dd9e44514162799d344d815a3a4faec913717a9ecbfa5be1bb8e61 \ + --hash=sha256:a4a00d300b0e1c59fc2bfccb53d7b2e88c32f200df138a0dd2229f842497026a # via jc diff --git a/docs/docs/api/index.md b/docs/docs/api/index.md index 58c21fa947..256eddd9cf 100644 --- a/docs/docs/api/index.md +++ b/docs/docs/api/index.md @@ -54,7 +54,7 @@ Each user is assigned an authentication token which can be used to access the AP If a user does not know their access token, it can be requested via the API interface itself, using a basic authentication request. -To obtain a valid token, perform a GET request to `/api/user/token/`. No data are required, but a valid username / password combination must be supplied in the authentication headers. +To obtain a valid token, perform a GET request to `/api/user/me/token/`. No data are required, but a valid username / password combination must be supplied in the authentication headers. !!! info "Credentials" Ensure that a valid username:password combination are supplied as basic authorization headers. @@ -146,7 +146,7 @@ r:delete:stock Users can only perform REST API actions which align with their assigned [role permissions](../settings/permissions.md#roles). Once a user has *authenticated* via the API, a list of the available roles can be retrieved from: -`/api/user/roles/` +`/api/user/me/roles/` For example, when accessing the API from a *superuser* account: diff --git a/docs/docs/api/schema.md b/docs/docs/api/schema.md index ba610a0773..49c88f3a46 100644 --- a/docs/docs/api/schema.md +++ b/docs/docs/api/schema.md @@ -7,7 +7,7 @@ The API schema as documented below is generated using the [drf-spectactular](htt ## API Version -This documentation is for API version: `449` +This documentation is for API version: `459` !!! tip "API Schema History" We track API schema changes, and provide a snapshot of each API schema version in the [API schema repository](https://github.com/inventree/schema/). diff --git a/docs/docs/app/build.md b/docs/docs/app/build.md new file mode 100644 index 0000000000..4d97b03f11 --- /dev/null +++ b/docs/docs/app/build.md @@ -0,0 +1,35 @@ +--- +title: Build Orders +--- + +## Build Order List + +The build order list display lists all build orders: + +{{ image("app/build_list.png", "Build order list") }} + +Select an individual build order to display the detail view for that order. + +### Filtering + +Displayed build orders can be subsequently filtered using the search input at the top of the screen + +## Build Order Detail + +{{ image("app/build_detail.png", "Build order detail") }} + +### Edit Build Order Details + +From the detail view, select the *Edit* button in the top-right of the screen. This opens the build order editing display. + +### Required Parts Tab + +The *Required Parts* tab shows the parts required to complete this build order: + +{{ image("app/build_required_parts.png", "Build order required parts") }} + +### Build Outputs Tab + +The *Build Outputs* tab shows the stock items which have been produced as part of this build order: + +{{ image("app/build_outputs.png", "Build order outputs") }} diff --git a/docs/docs/app/po.md b/docs/docs/app/po.md index b6098b2d6f..7dbf0de24d 100644 --- a/docs/docs/app/po.md +++ b/docs/docs/app/po.md @@ -30,7 +30,7 @@ The *Line Items* tab shows the line items associated with this purchase order: {{ image("app/po_lines.png", "Purchase order line items") }} -Long press on a particular line item to receive the item into stock. +Select a particular line item to view the details for that line, and receive the line item into stock. ### Stock Items diff --git a/docs/docs/app/settings.md b/docs/docs/app/settings.md index d415dce933..5c6e7815c7 100644 --- a/docs/docs/app/settings.md +++ b/docs/docs/app/settings.md @@ -77,7 +77,7 @@ The *Part Settings* view allows you to configure various options governing what | Option | Description | | --- | --- | -| Parameters | Enable display of part parameters in the part detail view | +| Parameters | Enable display of parameters in the part detail view | | BOM | Enable bill of materials display in the part detail view | | Stock History | Enable display of stock history in the stock detail view | | Test Results | Enable display of test results in the stock detail view | diff --git a/docs/docs/assets/images/app/build_detail.png b/docs/docs/assets/images/app/build_detail.png new file mode 100644 index 0000000000000000000000000000000000000000..59112cd1dde2fbee6042f903b90e6c509f92321a GIT binary patch literal 134142 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

O(Wl;a!{duS2n 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/build/bom_compare.png b/docs/docs/assets/images/build/bom_compare.png new file mode 100644 index 0000000000000000000000000000000000000000..4f1e124c4a139e6ab1b194e428d5c452650f21dc GIT binary patch literal 43496 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

rpBRCBj=e~;OZZN3YpCn&Byb^2}7 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/build/bom_compare_icon.png b/docs/docs/assets/images/build/bom_compare_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e22b4c1b078b1cc9dd715a56a03cca4bf301f15c GIT binary patch literal 135286 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 `#R;B-q* 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 VXyJDEjgrgGb)`!cS^T(Gw;v;eeQkU z`{Dg~KfKR#k08gH;mn+0tiATyYa61ZAc>Afgoc8Gf-WufK?McnF%JsL^N*+x!6Sd% zvA&?7JfJnzls1!>N1+D~p`tu_fP(S}oIUvW!Uqrj$NBS*;G7lZ-!Hue-!j3LD3AZW z27DVm!2Vz7;GZZcB6cQ@_Le4Z#FSV?nAy1AvA^SFe#Z(f_9Xhze^_0hLw$vgOiVq6NQbHm&eG^ zkc)}K#MFd|!`O_6iPy-Gjft0sgVWg1jFa2Q#1w^r^&Q{4ci_JMw|o0v_wxYb|9zj} zo&P`Y;ZNT|0(kn7lc=;RDk|#SisCZ(=L07dNl}#YA(Cwrls72SA4F8$)Atr!bXB$5 zpZ#U;R2qFlK|zC!Z}eiac(=T^?x3kD)aYx-!oq%&t6TX3Y4#fk`uFTnsh98G9g?32 zRVVR3din0>6W=Ao$+HWGjm7qA-A1@qXnvWw6nHamBnRk?q5qH5Y%!&OlYoNKCGvky z{tpbo%B1rnlwy*ke%qz;GM}-6favAu=qdX}w7}n~cK;SKO8iriCp$beH2MVG^^iD0 z?K%qu)T0yR59^CXI>oGwO@eXfG4Qf%tL^3#m@_w)W@UA4fT)7uAXiWpLQQrh^#Bt3 zEnG@gwqmAh9PNy|h@=BVsI6e`p;{nfv$@eVbDMJ^-(@#1j~YL10cQM+ zhK5G8XUrUNa(rynm$R3nfBwwIeBj^M*r+!C`gsOd7yYVy+~DJs07wPxNqm5Z z#P22D+2#hG;DCTO?=zw(%6wzXUBXFcV%(oIjT1GHIB>y85<%bH^NiSHSV@Uu%H9$5 z!VV)6!<&ZY(@GS%@WZcPSoE8`FMBGBEz&|m`+h%J)LYPXa&od?Y^pY$J7*IftvIY8 z<*R`zt24tyMg0GE_G=_n=&D)B?h*-QE!BplO@&(y4V6(+E@F`oN#Vq$9o^G)?K?b#VlWhfM?p#jx^ zLe2d=Ftfe|~my;dgcHGGC~OW)u4%m-Sq_-9zou zMjx?XS?gsOxv=kiGx81Vk@a9*aPN+&QVOfjPP&$UadB}#bW2N1+oPvf*KKj-lW>Ej z+7gY|M2VLtPai*(&)6WuB`N(`cjVq8OEBcRH>|JXxV*g5xcEZms;4|-P6C5meIrGj zawJsEy6$i~|FimiR8^Iu^`<&0zpK)pqublNEVz40W~Oql)6ULTLzAnkqcaxjy1eT~o ziwjsX#WUpaD68T38QQU#iM~4nGksYz^8=-dS&O!F4au*Gcei%H9}5eM_zUWkloSXI zCM_*Z{_vswQrpe(dP&ReZC|~7crPSS=?fag2hBGv-eI7>$BLWVd2En3+T^g*Q;jIZNe_h(&q#y?&Dp!oj% z`-ShlnqZP%x{8^ng8fXDxci5WMIU53pO1urfiOQm|J%2k(Mjf}Gt-N0mc}nm0y;VZ z0zM3sJwy52^g&In)|Qw+n)>*C(WRKeQDW=+U$z6KWO<$O5VqQwp!lbF@k_7;La zEc|nF1x{&cX}KoVhlZH+^!Tln%HJCITaOfH-y5rBiP?l zWqK|jk&D}71wBq=mF0T#v<*>(c*pK7lS53h*HQ%B+`NhksLCJj&8lbGgV8^cBME}r zV{p%RuEsiFm^ZmXB;%+x8P&70yz~Uzx(3Ut^P>CL6*AahesBXz!QY|z#l`dr5GHL7 z%omtTt>#OxG4s>Y)2{IQj6t)o58vYo6%Oxivc7%mNo3L)I88s8ZH#N+#{j$2t|w`N z|JR1S9$%77~YJoBWgt>I84;V&&LWVkDvb2|tO2?c0@;tCP*a%DOtr0Pm|bsp)*OQTF>cy_ScVy!_x`ZS`h2j7g^kHR{`R zvm0{8i2w{W*v(vC1)G!m{GF|0{{A9Qet+r0$3H)pXJQ<{!N$hHf#c)8Gp!;;L3s~p z(6u`;Qy41KPUW%!S5J;fkuLdZR-KWdBkiZOF@4DfP=6?kyWU{QAeEPw(?W?R1J8y_ zM;1CZKVK@1GlxHzmYBzBEN0* zaG`l>5sr)@Vb)!iZ)KXR`;@XQWOtG2lW*X5H_MqALEJwh^?V06br-pq&So1lVD;q5 zlhBOqUuMT*e|rLcJxA>HV0DoSe3Q3W_o%Y+M77FwY6{V?Oqn+W=?`S62LxKFb4*C!U_3 zU~?R0@~8FR9oFknW0MMh3hgwCAm^?#4a3*Z9Q!~yazenuu(bLT1w|>pLHEG^(T(il zPY`B2?l$&sE_~HKF_A@afBJp-;O>Ug$uaMqkV)Fr)fEJlFS;TM<;ei8wZz56)&Bhe zm@6kQUlt!#J!8|~6+xWB!N$$r?0L7O*L;y!|BHSBJ-NCo>9#?jJl}Nn+cznz9O`^5 z(M-6z7S4XLM=fK~U-uScNz9ZK^%m&i=sLrg*+5>R&0^ESV%s)=LK+%ZSNS5m(z4KX z5>crXR?F$(Uo|j@qm@NA%hk2)@1)YwQnd8ESTwYNtE(rw+%}Qn;o4Oe{y8}S*>qYQ z+VtXR88j-SSP-Fx$ zFPlTf_DI5k!)MQ68KbBKC=(A6c8Ki)eyh>n4A^%@_a?A6sa)Z5duN$KqX z%UdjbTwGjK4*}++Zs?z*j&_cL!9g3_(*0D9PYypcm=9W533Yr|Yp^m~G6967V}ZzW*95 z*yKhP(BgHm=(Ity%?F}x?o&MZ2&1pRVq@bhjR&xCWQiFq?9A$nu2g!f8?unW8Wl@& z=gCTak{y@cLT6c-p)Q{EG9n_sQmQv|bB#4BbSJA!UvQ-fI`_O`XCD&}OY%iUjVHV6 zT5-_kuh(uiQv+L<5x?ZekH3RDZ z@{O9Y@#@-@YJ%tPD!cFRyor*;i-U={L9=@6xsBmpcPA|bi_OT-vlZZ;ukWw>i}Cuy z!(VDKsw*pxtTSjNF&k(J%6=^=E*`yBQOMw(%NF@cCfMZRp}@e%h+9#quBw{%{k!Nc zMjrw}P%-iLK;!5*y$cMVkXPit;T!0P;q=xHsZhn68l9Ys)jC*R^*TAv03ms6D|svV z^_5~W2qh^ggoK3RfbpNeKb<7z=C&hRJ^Q>@OLNPhi%+L67fb7+M z<;#~P$%yfh$@|y%byjDyh%9)#Gd+S3fV3`6@GiF<2I|XL_99KZED3UaeCB&mMUAQP zf%tD9lt)-i+e(xg8Wgh%yoS=b-Ojg!eK#2(DQPMDvyHa*=+^^x`%K(*)g5HFYD}H(nDH z^YTrnrKNqEM&98Z-rW1x*f7=_n4UATUb~7q zZH~CR6;^fp?5XPPtm=Ha%Wc2Z>b2D9RQT)b)6}#SWd>dNr(Cwp3h~A3%b*}%Tt7jL zVwU_x1tp4F<{|)nf__JPS1+DqDv67m_AHBxV{a2$KEogra`@|zQfM_()yY_aEPxBU zUltAUUZ`%EAtS8%dwZqjW%U|t1n?EzXs9o6=iG zMn-_fX`8L@xM*D$=VyqBh&-E`(zwgHx!LEMe4Zt>pJj5J&l?z{Qc%Xc6%;g{2~`6W z6*tSjf8DWB*Z;keIFqWn`oZLce7eegTGIF2)r}1+W8-~6znBK1;C9RTX``FTK}LM* z#3b|8F8tUj<;4?%jH_!VVfg!WH35P73=+~70dp)-G68R07bYNud~9o%j0Cxr+wPx& z++1QL@BP(D5+=Ez@71xIjFlB6%cxS*>c4}&udnf;2naObkjByVyS+R*ojCz(HamM6 zkU>6I3wtZ8)YR1D%iijCNg3jwD&{R`M`uSzcz!oaUKX z9gPTonKnBEb~`7>JCL9&gEUfIed8qI`1tq<7;*&#E18}8!zCOX9B>nHd0ZM&((W@c%1HaF+{Iw0VHcUMt?CNb+zH$o*rByu9@^& zl&XFv@#OC{-*4Zdi6G{nSmO~W<@Q+a1NEsabkG!+#U zC3PgB(64nZg;LagJw0;L^3n_i6+w`|QYw;c1p14Gmq`2TEaKB&%P9 zuwE!9c|a(Z^=b-r~lJ}~lcUu9%O zM!G^0v=|c;6AQpsLcZx77jrKJl9NOJRZR5DSJ4AO_shGR3oC1`-1rm~84YrYz=_F; z0)`5&`toL1n_OmH1}s#8R9hSEvb;>9)l?v{QVmq z*ISc|EKlOpXb1IDdvmBF|$?7mX z9FbOke|bbjMfDFx{US-}6d)uRn}uWx6$Y*2-#x17Wgr331+K1CL727+v%Eai&U5D( zKpdJFn;>O1O6JM`w(BrWqC-r)9Z!jm^_s)7ujcQ!Z@(!CpRe5p%FfjtqTO9qM#%2I zY7geBtS$Ra4s`4H-woS?MgswToLGuw1Gwrnl+0(HxEXM?3INi;QzoXMuw)Kw7C=0! z%{)AZl8ejB^~Lv1s_KQ>{%kgd=ErZc=$9}3fT7KHGM?2)=35igKf1Y4xky9wBeK}- ze}SBl-l0yOcq%QGD>mKyoa8W+$^8r>b_A%ZIrxWmNeEju}&NZ0N(aT1& zP=UG)e`C<}Bl~j*@mHRDtE;JG;VW-n8icW-oegtIF1rdwzi^9NYVM*lT#gtHN zI~;kx2~Zo)P6xp8^*V1c5yUwPEWV}#WTr@bFO>u4 zE%R#ix`*LN{U5-F$(?c<8YE@>kE3IK?yj2gu8cRRsw-ct9m2U?JiDQQNs;! zK>8*Gf{47azjnFnN9obr_|QAlmV zI?y=i6jR8sUQ&8^$u3}IsO0a5-b#$I7z ziPu%%#Lu7fx|Kjw+`)8lanaF9>**=lS;CXAq|E(}hKAPRcM5CsL*8#gZ#P*Cu(9Fz zXh=BAxAt`+V#3td#DGE)zJ5I{q@tvR^@>o9G{P*8fW;u;STAL4>jwR`D*5CMc8P&V zzSxaxFy_73f*B_Z3&Lq*4*+-kF>InlT`I9&1q#)vvJjDyDsngdu`!rlR1b9feAC!i zO&uLA9UY*ycnqdO%gHIYxw-in(kf1tp4NCasR?;<($Y>kO{V7t-?MUXsH*%qJDjQy zOWRd!^?Swg=+D}g!_9`vkqvo_6fW}WB+IyKf2KCq6532}r3gfHkWQv?S&g@NR0GWo zOO)B5QKp0{C6~>zkHbp+6%Il<sMM0=F4h~j*j{f^L(5gmzLk(^Y->Z zqzjVclj(~KgZ(v*W5eau`~3;DP|m1&1`x019ICKH#gjjAE2*jUkY#d@bT(o?R#)P=CGW0Wt+40`hdm<`aw0hemmp^Ne6mpP8Mu$VO zZ`7HrO&>oCK1JI0^sUP_yM9_dat8oqu9!7l<55yobu5P<{1YFWW#Di#w2)9TNv)Fj zxCjlPVicM1h9fT!JX-|{Aq*#qS-g@ZUF(jvHl_L1eIPpOS8sd}7k?2bdel%079&`@ z291tPoJ_Vr&yAy#w=uFN#(G`jG?iJ1$TaL_0UMUOf^e+EeiD@eQ107?N^o<%Rd}3p z#c2Hl1G;cSCpnvRQ{%AP+b<0b4WJTIp%0Ilfl}k5b*2q3`TbP_j6`paYcP!$FhhsN z`RRrRr%e`B$KadUo{o;`&iq=FXLuog?;C z*-IO+O5ORwP`%a`N=iyP`4ldwZkPd=d;B#E%l|@9E+3-0MiRE?`L+_9L(RP`WB~s0%wpXGE_#iG> zp#vWo{$Z%EuMhHx^sK&tffldB`vtEH7w4KrU40c56>0v-DGys+?fOracjtauGz<)3 zT(Jh8Vb|A*DpG>a=|Mq9fkZH`qL2;(gq;k&1zFFQXgL=B7Ls9j*4mGvqOHZdXR+;1 zUL;*!x4G@lhcxL?p`Wb=M1yC5Y7eGK$nmrxZ@70vgw01(OUq+3vh3?q%%~ex#sEz% zEl-6k38o_?R&-Jl9YQe&%hGbYU!xQQ4Q;086RCl;bX9|szW!pm$BS~LS1unh6&7lT zR_A}2ZaYX6G#MvB__3G(IYL?4U^%Idx%(iHA^6*^)opCj^WvzfsGN>s*I5kOWMmb| zdA*Z^gPY4DaI)w;!=o=d%eCYZ!T>^HpDdzlMzE*SOr=goOMx2cTz-&WT)KT@m2n zNuQHd+RR@rStkJ!?{;*Y07{79y+q*X>3gjHbv@S!3{x_Vc50xO1lVRoWaMJYC!aXl zx`62H<&TIICn0at=z+3|p)LXM(|}u+61jAqOe{xG!SR1{aWqy4E%cDF!pFx8{Xm(c z#M9poWn%$Ty$i}izbJA*u%imbOyl{~0tN>xDlj= z)4c&l6o^Q~I5@I%$Vm-gApvl4 zblC*%00`sraO67%2HDZ1Kbwbe+naK8gaHss$9pjU&D9*NsHh?8#=6f0vp0SgV}H)l z%ED&0s*LEqghKEGSq~3G-0cUDMw~ z`}y+_Q;pcU!b|twDFF4qfGtALx#w?;p`j^D5b?$K*p@Kz`+-@}d->F9*Zn_}pz`Z( zq5)xJW9yfLjG8lCE@|ta#b;#Pt!-C>kNo)QQ_jlTv%e1HoJQ`_2~QsWDxTOa*KMTD z6g*s6S?rjcL@fFBPm(HT2_lAu)NSVeV<*-OvQ{z_0YEbc<$53!m#pkGVip@iR0DDF zQGqf`9Sp?HC48zxbplV-y2JVXjY%zm_}$*P!tThdJl_kj2{+6NK-e4mVJPNN_nH7L z@PWTbzj~?4#~0jovwuD=)qwN@X#1cDQ5gRgn~ZFvL~&_`T@ZQcljk1tDHV)2;Bpm9 z4OesZ_GmVS%F4!F)}s|EB^S);FCIq${l@;m4}DNE|(3U z^u;{+Qr9YVHVa3$owBF-;FeT_fVRCI@y0_yKMa5HPWZ9v*+g8XHyfd8yp4LlS<1EF z<@<#fD_3DjfOz^I{V^3(gyh*h1~`yMCU^rXm1=LWzSVQ*%(S@Nfbwujs~*zhWU?^V zdMc81w!70OcF{YUmYv-RL`~}{``bphiaJ|8kW~u8n9It_!oAnEeMJ&VuVnk_$;b{UW4<++eFEA9U>|`0WW}al z-xR&VneU#_)VaC3v0tdefjj|f!EyXmA6vg#ylE1H?t#C1l_-4AGdw0W^;+FZEWwlC zE3<(4F`lRt0P;bddg~^U7Pa*70z5?P_eNJ)959}OfIkZ%?$WPz$R zA*W-ZndGG@~H4M-IE33-M6nj#FX zmsQ%LIe)vO7-um?U@C>hXcq^qZzFjh=ZyCbS37li;f2%;C=gAq68n8#K?Xr9Q_gr-JnRDXR!C>v81?K>z=lf@V5_?{_mri@*g6OKvA-4h^i>l?I|etWx>6r zrQ~XCY*x0GKbo4RfMO~MNo-skyJN>+7}&oyrFVD2Z@@NqfA;NL_$?Neg{377mh%ex zdIVHwUnDWhYJ^2Z7+22#dDMpMW~}fMtW;?h?YOKgavYpo@Y3Sq)VMfeZ0uv8C~rRz z2laRr=okkl=cUYT{CK=%ROW~7j%cfu-5UipwTX_75AyQ+Cz~u_mCx4sn5)4H@_J7d zM_+DQXm4*=pp~379b4d;$)G-e{=C&^)6UaVLY_N#M03_Nh;!lTXZl~8Cx8o|q_fu6 zRy%>zw($kQjLrEEimzp5WkBn;TdLdzF#&9L&ILKJwTtMl?aV;^@3H!x4U=KS;gep( zW^ulQ`~|M~2MN_V+T>cIFKFYY-a<>j`C$pAbK4shf-{Nudna_ z7v{$QjDl7)#>U1pnXzl{cxiY6nW{{B2Ly!;23ZW~mR=ZJ{)8X77a zdV71L*Zs4)(tif-PR%h}lp>#VWGg&EmbiE2C4x{fQ%HG_rp|70w$@sscjY$l#D1YE ze_D22Z7_|K-*YW_?eERSp`h1A>92Eem3QP(-PLXmHIuK^k-cy zMSPP@6Th2tCT3=478XT{&1awax_*s(ns0bMImuOX{O#LcU~}-hTsEL86IJr>tE#Ny z^*d-0;H-A4fj;w&5BTtq>-~vg@JJ+yu*>W?Nb*x{ zRnC?j8_RU+?_u4F3r((Llaq<%Z*b8J+B`iD?^_EMvnJYa)rDEtChMxJcSl+!qsRmq z2bfIMQD44nK`!672V<@ZYq);Sii}jK$ZVb0T>ukASN$a_3Q@Z|1q_L*mGeUY=^I?O z!4sQ98561#c?_W5uG{FjKD5AZ0QW8XdG(wkf|&c@#EG0+gBu7n+lL#Qn+tH{a@Qbn z#Zn9N2_B>jT7NuT|NN)sLNk)1-Kk)}er9^QT(|c8r$4+xuT^ERjM9a_h=+&g@v~=B z&J4@KR>fA}3%H3oLT*pT6#x7N!7d%{usAhUZ#E}^3M`Om>|T*;!!UdTuUBC8B>Fcne+j_fj)sd@uj5oDd9cuC1x+Q2DPEZ%x+KR=T*k zA;GxiYdAUnJC2V}`JB!NVyGnBd`o($gu*(n&yozx2UGL&VQMm*1pkgCFzOL$Tta?F zExJh{bDH^b^&*YKQbi^M*j>ClJmr($8G>OVV9{fI`!*VR+t=5(+8seIZ08MeiI2bZ zxjx+pQ#^=K~hy+T{2oHVyls&lh(d+%X^K0(kUjSs1$+J)At&byMz;NG6d5GGlgug z`|ucK6(QJQ7c{#b5DD2d+$L>}w08e`6bvqj4W?xAq$P<_yA+tbTy25&hEBvWUF9LW z4GAn3yTOpeAhjI%9+-ZHC#sw~i}GF>s1M7(#6Zqtbbuq^?BY_=B+cQ%Ui6ZjYu+o9 zo5G~+;-N``_DcPd?_7-`bkHmzZ;g5u<@CpoAE{PyobTA!W}Cf$NAr&UuNFUl^Veq> zt~=AxD`j8!3Le&TWg!geoKunt36gXUg#2u6_tAH`!^ycbJB@mgFkxS$@m_M}=sK{u zdS7m>v`b>Px3}lRcLfnQz`^^9%nqBv*YGYVMOGAO4@ME_835qGG zUbhEFk=)VU8NdPEtTtC5I!!=Fo~GQ4u%rtvEP3?hLm*+DFudh4sgF%9?po08#!D>n{Z-Cnq~QR9;>lxZwKwn!uu}>3+kh zR?C#et(YcsH#o;VG3`(!J>g(|;@(0NmUKJ1Nuceatvwr&#;p(c&4^Er&&(Y9&-@qu zGGcyy-t%k^(q>Lmppc@is_MM;m%_vM?XzdkSQJ^TLf*fbZnWOKdv*c$xuJz{*jQZl zv%uxj-}!r%H9BpyU3jr%JSgJe;7DZBlDI*x?KM^tFzbE`4~@U|`(9qY*jd)!5rQL6 zoFY?dP03XpWAK=G^T3?yhT1n9+0&rSiL)bK6pek zF+MTT+S)2e>#?@EDVyaArtujjIpf`E{z>xk2yD!+f*nZNx+&EUK0mC~ELDa_k@3YZ zvXfwAxA@+r){Lu)_5gQt0pjn@WLfZ9bD2)FZku-{-<;Oe7c{2)Z?$&&j@!rUj_Bus zeeOqp#BFqKwp~EN_;>E-(tLL_R8q&~aIzIzsDQ{6ESWt|*gMadd*J^7R4E_&zX3N4 zmTiHyN`8ENd?K@!j4UL?0B*NfwY}0F3=-?u-(Z#ShzdP^tlQ+>+cj%eFg0+#KL;IZ zH>h`A*b3-~YkxR9Rv;GlZVL$@_|uvxtY&8syx?CxMO` zMAtOz`2y~jAA3h>q#$x9tKCt#-I1O{r?_Z=)t#?h6;6TY%D&b_IuK=Rz^mnjZT}feh){R zHSBlBQ#&dQ2$;1s`$oN!nDzMFi!_CMdtOnM{J}q1st~Td*xtLUMuR^_QAG)ECuHAX z*^U=Qy*gfJ-(R8QqzP0neE8LoA@|@hUJ7J=Bv&#liII7og=C!3z+lP8?=Uy9#(GLY zQL&<67D}F+nyQeZyLVRtha=}boIvY9|E-Oo;mW-q5DwixYfrcN+++$?uD!*D`s?UO zOIuD3XpP6#)YNQejsZ*2TLfN~fDfD3fsIuN*mO5M7o)=BHxsQ+7m-mFiYWx&_YY=E zG%8~0LCG|;Y4HO57|LW=^$?_>@W-bP>ha9P0x9d)XXpiqB)pDqArRQ9ED67_K;ZFT zLu>2Z`M$=}sQ9Fypst=6Dw<#l3JQSsYI`&&*$)By8m!Jgdr3ll(%kBG@hNLr#K+0d z)KtDK`tQ0dC;YmCN<`dD#se6Ges{j8{6^ot(CU_?K3ZcrMr0{1$m-Z3wPUT2qtxKt zd3@^ZQ7`c-E!ozg5l+kK0ue-51aAE%mMdUo1)xw$n8tL-Ca7mq*6hp=5l{ z7ShcXSfXIt0&9gl6E9u2jRX)Nt{f{H@%84L;#FtLsu|Ayj&DPcohL?{KniVHQpmu+ zss##k+S)Q0CnqO%^DSB%SL|$~md35Ry1FvOx~yPJi0yCke%ko}X{|+hLkFlQkfS6e z3)Rcg)41&ot*o@m1I2iB%Wob>fq6+%0R+x~MyvB@_DWta6t;B6w5t~Rdm=EK66^_& z>&K9M^>0y8g=MugPVFK}sE-~!nw^`uL+(X|L_nsb14LH!fuW zjRZ-x`rch1=y{Gq#wu64vBT^WrYj6Wc4t9ZNQvJA6kooEvV4MKFS)gi8=5I7C_H`o zbaaA;M8SN@NTl;3L$|rl8+o5mCmjZmW+1iZSTc&dzYzz35eqCBw0OjCLLEVqz&J8> zsm;ghbSvf|0#gYS*o}}!-B}UkOm?)W4EJ#XG0p`Z0k1JpJ1iG`C!OQ}d zKA4^=EweV?m#q%U`9x!GdSs#PP zmX|+v)@42KbFrSAo8#x{1J1^PgWTCu=3T!Q-*s(hGlV zV4_NWHrxhl%`De<3=OAQpwITYH~?)MvF)I>!3c%xy(vHm-|O&{nzF@?*&55a@8Tug z_WB9FPl4Tg#Mlv$*=o5C+E`|*y?~A$bued-QriNSqu2SKd|Kr3@~_q(KO9dT89wY| z(6d4NPBsynEXh&vDq(-aSeW|E`VY3orl#O-n`E_lan^Jm`s8)?OTLE($b!$o0YTv; zoGNC6cYcTVtD_Q*Jnc?TZQpsWYiVm^kh0YP2mnO0#$H@PVzJHXW^`TlSdIXeoaKp2 z9D_WBbFYz~iaT8#=vgUkPgGB()>;EuJs!X#!3KmQ<$+KWIm`yqe*qdIM#TD?CCVX%n``=$H4YmmUm`f)Qd z?)6PDOd(tKH&`-rb5}!*>8OK27Mrrd`xVQ`%8Kuok0|I{QDI=wZrNHQMyeOg3{Y>D z$)o0+_4r&Ji*HO)9=o645^@$1^n$rB!o~ddFFmoR%U?cN(!1 z5fRoJ@)8v_TmFJYT-6!(Y%8E90RJLsOT6KeSr)8<%oYX=Ptm&z+fdEI*yIw@+b>IezKX& zUZ{Xc&ZWx-eEJ}3E>uYIJQ(2JmZ!!Q)zC;vL^}{{&`?=tYxTSfJs)4+dgJAc77-hZ zoi=!Hy=U<3oIJZW7)w+}iV(OsZ_W>NDs2LtLCNARIh>kZ{yp zV9_3a=X!J-sKsvHD+kO{wDPF~Y5a$$urbgp#4^2FBXTV466r!QccxGmX$M`HVrzH_d%#Up{j6ViRvd`4Ipx zA|i#14K2@%Z?OdQ)Zi8%@@X583>DyT12=+kL?#2oiC_%U24DFuwsj*QR_soeB|4eF zj3y?@5?-}Sf_sTlzdW9hJ-k}vJVsKfCRbOpGt~wMPW`%DPDn`5DA&A#VqU{>M?rIp zdWE*_$B#B z^_ofN>c+Uv;$UtSi<9b;l2Hj>g$kUUwc;-b?&fdIJ?PW8*cMtWPuk!YcdbZ!UiPO3 zAxp)kB}{4cJ-XA%swzSygKO|wP7aPDst#0&U%!4OG@b%d1k=j}I!%&R1XpFAZfjUg z@L|wX^!(i|i(Ms5Xx|t#HC4T|srWt2z{<^i-BLAK~7Gt2Y~9}U@u5dTuvmsds#$4z%5X`a7@ttyL!H#c7t4$ z^_hD+L{Gx3;fXEl>^z=2!7y5EQ!2S_WvUdDqN3mG$%*hHQ<2&Kz3%8oe#Ku){pQ^p zO3Lqm`iO%SRh8c_BLe|(s2_nSj1UDKjzPcE3=IuM1j8f3%1k!Z930*;74@9J48?*I ztXl)rnRIODs^raN06yH@UWH|5W(EZXABpN}f(0 z2$v((BfTj&uj#gn3Lz8CiLM(^mDaAYsPsHbjZMs|@Dik7Z>qI~-v&f)CCk`yN)dBU zRGG?d7kZ0+YtygPQ?GLB8^L4g!BfJltuc{<=iF;!i}syuO25GxmI01POEHH0XQfHj zcdxZgQ`(pMOFT|C_GfG3NETb&>SLQF9*&!nU=%W#R*Q@FfT=n^m^qVgn~4R&1H0M4 z-gHRYtFZ{;DNK@SgSVX6YJl>Oj)tng#=&W|T0eF?o1|CYfAJ5$cc&^g2eULT%yK7f zfpupm9+ts}H|ODiSQKLF-vYoX*~gw3wLj zRn>aUR2M5NE1g0n$gVms@(%xSDuQ-1Z4P@@?`ek}vDox!oAValldZ3R4wm?xHU@$} zW5yCFfFcNp%~@=gGT_tDOn{tpXLa{vrTv))vx&*&QgRJQzt7+^ zlAvAIQqN^uqYrexMhQb{fI&ECO2ES?DY=<8-p5t*M!Ec#SxsLJG-PD)tNO-m02Y88 zZKW02e7CF3pID+DVnWoaYW=S_n4?zOgP@oUb?VPhzHM)9fsdmi8%ZMc)=fq^h1c4( z+4b}ZZ-qg#nF<>JcZs-1pUcp82x9!4POr*E@k3zo6_zvB`F zF?D7Gi1D#R{>alNRbOT$3D3%IS|=wbt~91iyXT@g4i}jVpo@gr^o6Zx&oryCWyM?t z(#vOTL%xQt4t%(7MKWQZbLXF*AIRb}#oW-n35d=S3p(E(3)ZeOS`Y2lU>?gXuJ-Q; zCjOsZfa+>6yoZOIaMOPL9iIFdcJnAFa!IcZhR*!{q)0M;A_4-9a*0VwyoOpA=TP(* z8DM5x%OoE4!vNbR?`vqPb|v@2@82C;D0A)zk{YA10CbQgTEAl7?xAS)5Gebq(1cUq zTtl97+$;|wGIXiO8};(kle_EVWEgx%EyYs28nr}LF*@YNb zIN-?qMF;*KD^NT+Vab*4{*ki+1{g*IxPn%#m70Fr9;XRt&tTSTicd>xc0HSAn|o7G zQo`>dQ@Kz&S+3)?eViY=Lsv+RNEO_@Z9IuJHP1*-pKYkg+4oeAb=jTD5Ok|MKPOZl zDO<=Ed9-8LNUPmL-TJzGKwm~%QP0%DgY7<9Ml!5#`Ny`oaU~vaM1;=vBnBBrvZwpb zIOIRTwShJ3X9|;pMe4NSUhh}{KWK4ZxjkBy%sZ43qsr|JO9G@<`2}IDiWCzXJ(Xm5 zUO5kBV|SO|>wqMM;kzh$>NaP!?%CMrsCt?H+49O)U>HPK(a<12oqJ=|>;Lsx-ySEx z8|^ypnS_3ta=0>UO?OqFeK7qUkCa!SZY&;y25@AfQV0SDmj+DOljV9kDl#z*F1wR` z>kRAOf&vad-&=)ypY2Qph7rghr9ej&NPmiCG0qPbbTYFYcgA~xJF#bszN`4VPTC}? z@)d#NsLu-l7(rZUr&+J2DD>B^p;U(4$Y#a(%u951n8?3u1aD6BISRFfY*T;r2o&^S zYz&;)jeN%|yWL9xdQC?35HBrlL?WY}!rTNaAD`7k-@2R>B(IK9k&!*$`}XqFRp`2? zp}+P-^h^RKTGHiN$<2ogzJK>YI_s8=p$|ks^P!%zA|eKZ3%kZ)-~9FYxpLeqkJBRs z$F8qHl}XYH9yG%w)7^WrACoJ&HgEswD7N!h74+_t-*sF38#p$J1DR&8is{JhR?iB}8mzqe(b^-q09UX?fvvFIpjqE#O0U^&f5yqY4Dl02j<-7XqL;?3V z_Nnqxmz0W}o9aX3uL=JvOc-Qh0)<}4!Bp&$9)^jX;6(d% z8gyedx$YPDOujQV3#h255SXy=deQ|d-4f#Tbu@!v-911V>=9nz1+^?}Ra6R)7@I!D zdjgVGuFfelh%~4H&}a-7hx2(`Kbm0ixmIFF&QzO&WpDLE5XI$Dt7QJ#b9zviaM~P9 zQh*@$mfY^H)wZv>xaxocGe$4u#L32HbXL4BH|Lx-B9iY>Z6*b&9r^74NQS5pbZrxJ zSY+qqjC9mVPnGMzbbh3zrXGM8)i(}FnBR>6ABrQD!%~z901gb+g#|l$*Vkuyn5D@_ zBjn?rCs2|*dfxE%xvjmsu%B=sLc|RyQ2;S-`U5&1@8off&_QGJFtmm?w|Bo*>^I|EWG2EA2%?6QfJykxTYK*e;E=I~V3N5Pp zLUg&k`IPfftSLGXu8yi88>P`i@j47P0QwkKMApUL|Ll?{-W+!mwLvq`ekb7{*~Wa>_ACPAYP1dF^l78*Qq=?kVGjEgxk zCmS9vPuJOcX|F_*>KqbeDL^)sw;J3>*e3q?RZ~*_)~L|_^)p^HSvci>4HietZCkpn z{$B0qEiol~KRW&)_Q)FPAqSQVv?GoFC&`(|E zGrV}Qy^v7j+`+tQ)mbAOZ(S|*oHvL zYKh1~Rt(8gW|Anow#e`*K}L@)ns=inrbuLC@Q7*BpR6?ys$#g3e7M8tU!0q>aV~stW}NxO_pSBTqH^Hv z%O+XQyWDgx;+`*KF8lH02Q`yoPgm|(j~?LjEOc_!%ErdjEcuZ%HGAQ{f`bP?Y*snO z$6K6CJM7)ER%q(Xf^ASKB0Ix*GyCYJ+zB<6Xh$-GQ!>dxVVYle9({XA{y^@B-UV4- zzS?=!K5k#cV-U6~)#&RvRsTTLN2S=^!I9>dH<};NZ>mPOu3LVQGh_^RIB62;k@zM# zIdo~ZB$<7z=A-@nSy>U^`qLd1qf}Pb*5vhF1JlK0r7_7~yr6cWHY$y+-owr{O3fH_ z=-z{BDoCkH%=Ra8A$6OhNo#BCpa{MSbH3Q8B2!gbe$+cCZ5z8EMI?$LD&={E$puj! zC;!s0bT}XZ~bCa;=CYH>|BA!-NPs?={Sc$OE|YrH`eh zWp4s6&9*So&k$Ynx1z&Yq3ctQ`$k@*q`yr@b31|#L%gJn#Xpgf>xM%TNuEZHTmG@? z#4CeLwR)FRe%BbrKDNx?e_n~$$rl}G0ipx(At*jiL|$)CHkY>p1xjOAjspClg}kZb zY~fDfgK{z43B~x1-pnLu2$MHu_n{Kbd{rg?68W^<+QdL#-|gPXyGvUu8ynhD>O^rY;4s~WGIk(e6=FT{P z!lLW%On$!KuTRNs=U8Mcg_A;agTQuQUP|7%2S_6 zuX{Y8BF(WeoV}%#CZCdTE_|;&f+a}k%byV367Pl||Ai5ivFY2KP{_`rPu zjCcpjbFXXw6Nj3hZ&3K_Z%So|+#VymsUzn|n$&W&enY;?VpEGHsKjFNua7gavYHS3 z)>D3o`Ql(T)F%FE9Q zG~rMRe>!}cqsOJ!9B{;yaty|pg5oMzNngTF&cG0){Kl?p?7_wICm9)n|I~XReG!eJ zkPyuV!vM(g7OQ;S-Q7cFie$-{KDu0zMT1hAlf8F) z1r8h<8XB!a7XvHnmDyj5p~p9sz089JBCAul-fc}3hV!c)m%YghdR#05#qCJGl3%X$ zI$){lDm7zUZvBk?1H)F}RNeOz-{~6;H4$?Jc#3AQwqs}iHS5yC@(iy+C8_`^FjhVB zoT7Aiyymsx;c`_Hjrt{ESCgOv_Q|i2vLBd(@T2ld(MWnLw~_3V{3G)FXs?cRO-)QD z%f(gLU*Fmb+8+VK#{1-X$^aQrxC71+Hwki2R*6w}l&T4+9=#X&B>m~hqZ;m(EsjI} z-lLvIb8gNa`L6w3Y?WI$sdrbm%!Bl`5QtnhPTGf$A99|Y*J@lb?r$)a^m>$Z*(WTY z^5_T!8m)5n#4*Z%J4<Mz4W~{PfW5X1xOyl;{@1gaM zZm^@}yQ|F531=r|X0{DuJ6~U2E)ioObq{sDBPS)j>WNnoAGLHoU)o7RUex1?s86es zc%F&n-%K6g`TTfeqAA?r(TcFN^j;u(gLT@<>2e|hzh)i%9@@_>iFl5~SSE9Wo~ZFZ zLgj*bdgPD7EyUbkIOTMzqT*mXO2YqtfZ*w9JMcwmhu{ zAKk_Cz477U@ZP+a_dH0ZrlvC)!{g$nw$~BY`kD-`69?%uL5j2yexh|5kig(=B41!6 zv5^Es?Q$?LLS=U{3Ay{M|FXeoHBB7ry{+xx92qEwAM8D#42U;enj!^~lFTRYn^XiF z70qjCh)oASa3gl(s!g=C7~Q5$(lPPa?4B!}9E@z5>4YQSM$QZl`TDiFSg$iiovf|z z*XNNgr&(o5)kJ2g>uqO*jQw(Vyl8jT6qe_2#bSs1WxOxJI>}6%`(2>&2LWdQ$M~Pt zR!Z91yFSS8)*0|61zgtCI|Kceuj{ooBf1f9Ev6T0Z3kJGyL(jF%%+Pi=ZV)Nug?Z| z=Mk*IHnLK}Mi*bd%cM)N!{D(0$&5+^XeJg#S|)t`+nPVNuwCI3sV zIc%knx{ErhvOo52R&zBZ&Hr-v=~HZtz4^!aE+d57znf5pByb)*3Wipel`%|JQgVA^ zwPdZGEYoEpt8*mV&T>n-mCh#}R(Zk1RVskGz0*N%M=84QrSl-bW< zukPaF!*V{_I$hGH1>G>@4nTU)L}h-iBt-`HgfTeJ36#m-Vd*3DGfdMdv$ z`j_hU5SP_12^58!vlWT>=HR|@aAaYjUk7;{gz7EiM@5|^OgmTpX$Xe9aj7?UdqK9K zb!pfw03Hv{o;-hkaBBV8 z!9h_(#0neutf;Y(yh*6#SuJKfT+cD0nRRkSKAaJS{Mu91(A)X@8w6Mr#kLP;KcxO* z^T%UKFPg(m)=n1j6;Z3U!DF>~)>||*X>V#_T204?#Z%7%<=R;o-aTIWD=8TPhfVgJV`SXhT9xZqnPcBZalks{kZF?+($k-!=#KbP(`Uc^i%R%N$?L#%f=^~w0 z`qQGBzGAprAU2BG^~#_(!5@#s`^@xT1x^DHLhANaM1+Lm^e+o?bGh2I`g|8@poNL! zaxKoT&T5GSM;OL)uFp#cc*V`{X8#U&i7xjf0@z448VA)ND+^;hxAPImKC*mJ@7(!J zj%+$nsMVCY+6ZzMdPWQ1hBudYwIU{dQrx=AbP!3(n6r)_| z@L?d1t~Zglft|9-WpOXM#31H03c?JX0nh$`L7aqpRe91%{Pa2sv}zGC6fbF0Vc(bz z|3KUVjc@FVgqF^m=yS}C28X#9hdGc8B9$T((9zlHC;1Id*wClZzmC&t_EkMBgozn} zGsFdI4Xg;FWuL(`(WlFFJv}OM(0f@~S%d2s5;O<`q<~6=q(C+nY|TM%?k;y{u`O=@ z$s+)vT{qWrB;~I)AJSZJV8d;)6m zG$QP_XG6aQP$$deK$_e@e_d82&qBw@xZ6rDT1oMuA{1`S@Eir!hyw^u@mp76VPxz# z^2P4$@c$kVpnfs`A|b~NT$!9`HqW??Z4fnA=qX_h+n3<(IHEwg;@^L5CM{<>yv1Du z`8KlCx{|jg)6&voro6{5D414YHp_?M=^#XfNyPQmaZT5{M-mI99h43MxlD|Vmd_Uq&GfpN zM3n0EZKbWGnPxpm?m0U<8~fO4X_1b$2_yX_%im_SwA}q;T<%r)u@3D;BmaTO;PvGl z>i0TD9XoTJ<=gM{i6%ruBqk7=*FU0}Dy>GD=T5%QQ%bO|5cJuv^C7khP2S1r3{Kp}WCNy@ zh>o(QQRv#*n)ysMyY*47LV*U$btdBa(tas7I!~oU_pGZ;Tav+I2y+2$`&Vhq0qWKXiXZipGk%xLm*?SFN{l9P86+@C zWl2#gamZs>z%&4|k(Le#iu(4U z?e=d?aCMcZ884&RH~3qVhd<+*fr&+EJk=nkF z$UpG&K}}`X(T|GcLizHg&8hE0+oY1-L{G_hu7vnY|18VymoHvuo0*lEUv3Xcgb!v& z*1GiPioGP9KSz`OcCC%`p6bT6)rZ%e*kHI9mZj>Il|>~NE(f=TZEnFg{alQ8^-lNS znm0x^_<8scF0{7JPHQ=py?K7OyZkP@(1im_U$b#U`$NEZWXeiQ972C<4C zeH*qeU0Yigm0N2SnC^>;^wXf@5%1<;LM|!T%RE82p=Y3n@rkmH5=oD-MtDk zjP=X!!1oEy*oQ7gLR7M(wD1WIwn>Bi?(s3V)rlrvxBdY3J=vS5AQ{q-vyTt%gOuOD zx*BEH#~qYUsx?lhBjQh;(u*$=mNWnJG#BEpUS2geQV`6A{TTPL_PwG=Ijwt)&+d4t zxpV6zbdHW6-SH#2Cr{|tq7B?iks>WcsFLzo8mQ@!dHMWE|J&6zahflme&f|a`m&9D z8|Oc7{gdzxB#FV#JI??9OkeD<{_B55+9dg(7xMkLSFY6azrGuiA*%a-dFJ{s{_l^5~Hb^55&BLM<{km8zIJLL#E_-M~W+Gfbp= zeO`VFLqkL3lg`H*2fMqtrp`$9$mLBLy{ea#&YYxO#|tPKxP<1b3|ce92IG^_!cwRR zypH9gTg-6B{vN9{Xo!w>Y}%Weii_LW0Hil4=r7#mwY5_L76c6p&tRvHVzwGG)JNaH z@^mKJGWRflba8FG;S1X?#9q@dF*T6zl9RJDzXT6SEhsWPV@GGe%@1Cul%GFWc6%q2xq){UcGERa2aKV!E1KE1+T)`eez=($rly?m~+;}uix?tY5o%EU=t zX5N9%q4B`_f%Sllwug=fcjyabp8s%t zbYwK{%0nkZtK0Wi=w<0Gh#N`KWwPfr}rdpwoPe>p9;^B#SB@; zr1cS#0{I75r!A{j94oGzEI%uzGX+&%7gel|zfS#`UA2k7%=;(clvS__@3txCv}VAA zJn<8)e?{{dd3opes!8*bvM0Q%bCR>EGb50g6KiWP_8?LyUzH31rj_y?pXB7noFZCe z9~3W%i`RMo_RaB%J0Cu_5%_x@U@p0?aXh;|Y;gx6nUk3w0ggQBiM^i+sW_LY*uM~RoQF;*JC|4dI6CQbog_Zhd`+9kWS605Q0nkH#@<FGRrV9KHpE^e4+hMSD3DZf~TwEEw8AwvP5f}w0!XXiPeS& z?^nV1>N6bF-y&}3k$!qqi+a3WRjHa1@liwsspsHmtO+4vy=O4-=NUzPvXg9N?`EnS}5sqNiy?3D%P#qM$YBV(5H<24|C2Gs+%%gMXe za*TRw_bp6;I*rdbBJFLMu|-yegKv)Vf7BK$T{99VsLqYXF6q6ztg`wMJp8k|dg61U zf*$$Z3l3`n;ZCYZClUYlR7US6P#^FLzTO&IZ{q@Br5&g!JcV=++E)_o_| zhw9G!%v9h-Iwoa?gV2W$c^VZl z>vAZbTA&0sGBPvPo)8ol=jVUHL`DYAU?-s{qr z+}!@_rAte=HFn!%H>t(qu7@+cfo=V%lW}aQQbGv-XY9tOd*K_K2+%OQU1mqfkM^gu z#;7O)tXJ=_yRqcIuDYF;oNR0|IST5o91{h0_NtBC4QM7L6K`K$y5>OQ#K{J@r zX6CxOxyjj$x+D4qdP1%5QC%P0sJC)*OdOVmO-6z zZQC zhxaZD#Bd~gR%2)7=n36*G9-v9vJbDeNvo%(%P2jUcvV$nktHCZ%r%OKMz?{O={!YI zHyJWdS-h)>ioFO+?)Fx4P)O?P@bU}|6p)SWn=T-Mee4x zBNrDw>t#jJKEl8Pwer$>e@DcF#9QoC?;^Qdm4(H|Kal4{%5F;XD#fa>f@V3-kLYpNQ`JC|?o`v6YbVzQtiLx*Fcp=~ct9 ztjkWF>FzR@4VXNatghK<6dz>F)OBZi6$@E; z3;k*O@B^Z!PuHiSgRpoo{fF5YP8OGO&QMT>`0YeWE$1nkTmB?8e5R)^?jH(5%KN2V z1oIx+-U-Uf=WE5wYnY><=nSN`TQBuc)(GJ|c>?G0{BWIDtFbu+K{V3$Waqu2urQUi zwVyvh#YbV$5>ZezW#T}0gos*Uwq7!Qvq5@~UtV5f_Lt_^&Lc<<082IoCg!}O73?>l zk+YMMArlP?52vHerI4`tx7KD%38C81GcD-ifZ{j*LAmQWol^0SoD8^pp!l$$%%Hk; z>*{GwqKT8fA2hk4gJE|cJ`E)=wkpmu%uWs&2;`+Fc-!Z${Oa{<3te3FU(2d4x^OYJ1u?Zj$K*Zw-&SO`%73cGr$9D-aS2a$)yV9XC;7?FJKE&+{`l zVGvbNNe#+uh$Hn|FaO>#Qoaq7h@ikq(I$|DgxW-Zl<4?<*?slB)0l9s})&&>r z$(u7}fixmX18fXqbbE_LN>R~2s3f!6iH%&Wiw8EZ#LQaKjJ@ysP6C; zt|>nkZR?~loh%Q9PY5}js%1{osluTuPWo8)P&|`HbBL>Ah44@)6kjB3Gbvn;D~iz9 zNR=4ma!pk;*|U|ASCCy!Kd`QJ{!(=Z;lOWxyulR3aa})ecCk*#B9gSmX0_Bc41tv` z9F@X%_yAUryxt^H2y4`9?g}4rVZT8J{Sg1Z;YsFNBi}4HSjms(IV+C&oT}Q_T!eH)6uVK_Qw?fAm8D8_Usu3-kaQ2&c6Zubu~l^_Yb2l!?Ff_&VNaY9$w0N*;+m#HGi0i0S`5eKZ;Gm)CF217gnJAV~b{yG%lw6d1N|MzcP* zTrigtH2N~>S=;sUKGnFotB=W{p)2k-th=F;_vhSZa}%SV2%7tec4XQPOG@6eIIJl- zt*>q(ve0Mze4Cx&2gx^XUJOkO7b;WZHPa1)f=aA{m^Es2LLHjc?+aac@IUk?&Nw$z zj{jMDbSL=ne)ROSG>2BS8nyTnNoCs9j?b50T+GUbxdzK@ z3>bV14WCaf7)A+@ytluoQ;x#%?kB%Jm~eDMG(1Sc!q@$qpK)i{>HYaN;lpvYFujR#u*Doo_gCFvwr@v%-KCC&4Ksx=#$i}vOjK1Dx zxu59i>EXdk$YB%adYzP?qy;4DdZ!OLnR853NM1*Gx8+Rr_vb;~61+|;JB&x@K2VT@ zm}zQihSiSx%aRVmGvK2sWi}t(d2~@V)8-?uYQB&&nBGlN(b?Hyw>5?P==Z58czB!U zTP63;k;?`qD+;)|rmTxglfw1uXb5Yvx z;uSM1Y3Zf{RV5{MW5o0fHz(OO!C(BR1nb*3IfD{1g9Y|M;HcyO$xnPV|8(tWq3b7B zWRU#kgn&Tnx0tWT?P=3lmZd9Fk0QhHxb2avViU03^o~O=atp3`HKuu3KVLL{7p%)q+U+Q$weqPy(i;S%=7ju|eC+&_kxsYYb8E9$C20{RgIT#E(;2K2UJls)l;-fsPXAX3x*?eY%|Ui{$z>x*?v^Y=o?Y3X7i zWTN0WL(zMY>*=W@Iy?O?(fW92>5wL$xA*(~`^3CfOOva1+cN|E`>FXorvVSq(Ei4- z#v~+c&CLmI*{zSP*cg0S(qwoBZ3_iOy2(g>hBx;1tYdR)OK^=@)f9lv=Lbck_OI2s zB>koDd3+T6_|`rG*S$jn5zp?n(cAl*55|-zMMvu<4n+0GQ5Nv<5X0;x(aqP?w6ESG z5<=N^7TWq3tfHZQIJwvJ_5r3n8|)!i@AdWnWXZHnuFe;N_7ZlFgo*G+1Oz~sy({nQ z@GZ&QDly1c#+ltIrTNn3UDz;ruhhRgf_w@`6pr?~@j))PElM8?T9IlRM zN(g*)J-rrq;Q~E-^n;aOeT{ByVH#}+OeD;;99mqMC)1NiBq&G6p61kPW^cD5wR)#M%#E}H zrd_pd!v4cjR;;6x69Q^3k8< z=6WagS;A`Ws7-HyNN7mqg$IfGw2kBEYm@vRG58Bt9ubx?T*FX$r>{4+w5Zp+1fNx8 z(?t^4mdiotsSoBhKGAvAm57(e-bR*56aRh4gtu=V%*aR2uxxGlL-De?q?Hx|I1P=B z$tfux-APK%mmrin0`;GFD+R?%tc$h8R=wr4aSR3wKU?cTw ziQzOr>92$aBP>kUO6Yl6Z(b6s{>jgB4L&{?n#In`o2dMIwAH!4(b3HDA=bAQNuua> zse^VzUy8kk6=(ChlCr8{6NkliJQ2s?XhedNSnbTmo)}{yVZJJcoOQj2Pa=cNbM;Xj zT1@)eqyAzF2fOPAMh6t>$!fOd{Z>;@P*IYi-k)8-#u1<17;^f)w9h1C*R{;`kcRFo zANT9Kp9A+9@Tu6CnO{`!y8eqVe8bDzke%(zeJTf^4>(b})du`*EvxFMkT-Q=)nnM9 ziJ~)~kTaTleZ1RLS*f`9CmEo)(lDX#GJiS2%XaSfv5s@ z1`(VG2WRd8E~K@bUb7VB&lwhNqudUcc*o~H$g85>vr3wl-d9w%DVn}u;SnZFLoD0Y z-X5)@2>I#jtB0SYV-6r7wU>KeAiE-kPEJex>RefZeN$K4ZezaS&i)=374 zA(jXET@K9u;U@W2Fc<$`g`SOEu!renYO2RRvOPTYWZN0D-tpT3qMc!3k^TDvc!hDa z$8&Z6jm8?B05&kxxhipN#IRd-3N#&#WQvzFX(>-L(j^v1?1Fk_P2iIxuwa?}dc z>vs-ZdRe-Ve@4UYOlo`Onq}wyyY)0T^%DpI{`_Iw?1IVZxh1j?TsTmDUmwSgfk?7V2$a$cf?AUv4WSMjQolvL`Ig;qLoQlhuXJzlb9#XSxx8Nnh2@Oi#l8%QmX;|XmCh`1}t(w}(R2^jI~ zi~Wko$mO7^Q{4&20LzGR!(Y6V-)$2+yZVmmbM$*%Ma z4TV(`NaD?j$Ln674U0aF%$em*M0$0Iw-q ziR+Gxj<$per=0fYt2Tp-z%(;5ZjKi4o_-l=YjZd+R|8#gqYI8<3T!8#?!F*r_w<~P zWt$Qut5}54n~SI67KQpWm*EPZh2p^5ORI9WDOwM0M6M+69?dMuES+*K0GR`WgFW$_ z*tq!oo6b@Sqa;i+_CH>0h$Qg1?rlWpR9Ab~yYuxXz`UJu-C_rjq0y;SSWHy9*FC}P zQ#E(ucQh&r>l*!m(Scv>fi4?0EGLJPw(xKFjg|PKkD*r^5?hUwMoIK~^cb^RG|4@5 zHHoWgII?j=5#74;%C%+jZLdBj;6F4j=O{@(D;XW^RhQJmku5{-w)v6kd}KMq%3#ny zP5a`kDX@n{4o6+GfXy|b=dSyMJjQ2e=kA_u(>ps1Yn6|TC$xblk68L`+EWvV*QBKW zxAD}vK)uc|*^M(x?+x5^@X)AtpeLu}cGw95A7?S~E+CTVL|g~$p{<0o)F%net*uox z4TM}LCfYehgZd6mZkf5f1J!hqDm-aqVL5@NGOzNlwK_XHV;f3oY^iR>bw*GSZ6E;- zij4AkWS-MOQ)6yT`Vsh4AFXiP%?Xi-q8^E+Eag5taQN6eXPxJ1 zD{GhsV{O;=9!jdMcmMMHK1Zvgt23wo=;&V>&=-If!zyx_0U5;4-d<*qE7VTp&;9wQ zXI&lg=-=qQ;^K^aN%Pqy+6N}@+FS1Q8DkPpQC1AIFr#1+HOeL3lr(01G$!j26v>(S z`D{=9mc>fs#mJ26VcoYsfKHQK2E0MK0cdwz?k5HsP|C0QV zYso`Iq?3)-G$r*O!fNtYE^jY~vQys0Inms<(B%&d?3gvrVYU*ca=VxI$kXeKYd=xw z-t2Yo^K)G_5h$^j=Erjd6N<~Cp?FTT$%?QpW1OI`JyTNV5YxPt8O^fqZPG51p66G^ zxDb&@j|^6jm%q**i4^$Bui@=2BpP|izXi~OW!^av4h~;{6ZoqW-{|4@?gPZp9mVKZ z?fW9jyS?hxV{-I4I-lX}N)ye$^n2{fuzC+l}m&a^at-aDm!^=e`g)70Uof1a6+8Gy;DJ#kA_#cP<@ zlq_}*lQ>TnWE3jm*i9sKs@fnc86*M}k+=oi%fF4$5cw`LwTT zk`6fRw#RpN_(CIg>Vz$mcoxbJH7QxlJiTqbB~)grLnFhVxHwpOO%XC1Wu1O0;xg%= z$zi`Njh&)v6ZyWAQ}JHTk;))XPU}%W{lwXOWG({9?40=@b5C&2k6t`LcJz|tb~;{{ zz-x+lg7?w9;*zZ`J125ZKv6L)$HTmrXaDML=hX*0IjQjQC!Yqf*(lwCSbOIc0Jw(_ zCUKR?G0&TIQBdHv%d}R8sNOIpzdaFc)4SLdJpj?rRDb&PNpW{FTd8Cj9G`w&-IB=| z8jP$<_0_W{sh9Y zcB78!!v>3)V*d%uF6|=q`h`?0{pGEcqc9*+^3*EavEnXVdOll2+PPKv0D?T*#gxc4 z;-|Ma1^e>XC(oN#D-*c%@D(zkgK|Cle0ySO=t=%9-*;@l*#P+}sahRROVuSV`F)Xg z9xirm58j{}fsBh61zo2aAOVV=4BVXgVMIiSgMHy1V_|>RA@CqOu7H+QE0{DCVcvN< z%U%7>zjf)#&1tL@XTT~hz>ri6V%hjQ?Pk*@J~=wLsnl6&+zE~h{wQ9{X|q-^q$waP zrhPDVC|>ckn%>tpoxaS(F9YzQ;|-aD4{CBH=R=FAZPQZ+UsFFyAY>;Ip5cp!OXGIK z%j&7*!2_4Wh=VwDZ(LQJYCPpkTc(%x4J9mc3?Bq{;wU7^Gcx?X`4j4ipaUP2gFbtRQwAWODsOd+v^rkU(r@Z3X?9t&I&TJBI%8S3@J)_&0hJumxoL z023Zs@r3t+L0C$Pikn*;To@gTelU(TJ$s&VA&;oXIx}N*9)=l#3gHz!Yk79Ih=fFbp#Ns`cZr3$-h`_1YVu$9 ze&y;;mh%i%otpQAJ8AHg(KZIkP|GGtOi(LvwJ{Ifv`#f5{gm07$|%)O8tRVI7$RLA znrfu$0RuoRS$+P~QGmW>u3d6<5c{s;{O)*`bg^%Gc@y*D#KA^NZtCBoewK!fx=wX6 zLB;nrKuimDD-oQJm%Mr{!!J@Eo8%P|!+MByjEe9&{cOOfH6nXnSH<@Eg8#@oku;RW z=0~H8x|~8pCsj@~`m+?E`S!uiq?O9Ww3d%_m+^?#%RW_?_)r+?D$3jb?1o-Z%I0FRuk}Bp~Yfqk!9dzkju{ zYHZFMKynXgWR0U~*W(rK4TIj|5dQnZc<~7%0vT5#33Ml(IlnUccAnnGQI2A9HrII_ z9uaZnxS;v&3vaIi)Fgq=*+JhO+kQ8xth5@iiW05vzMx)oZ2PnGQx0}YqiJiv^a5dnQNc`l*mrvH zgXby!`>qiswv;BiY`--j8i9t#VcOQG0ec7Ps`zmEU!lE`eyg7f%{J82tQ>_MtAWBG1 zLML@LMs(wOWRJ!zi*3B9!wRAcmV@w+;AQr;tl`IG7ro{QMVf<-d=mHIfo4fNqIr3K%ieZfr;nAzLw%DUw&h!vfJyv3` z&~&%4v8gFDMG3#7y?wmSGerrQ@o}}^ z_PcUSF`)oRWK+e4^zTilpius|(%d;>VdUIoBmf`%?JX#>bT$tE#|X1=env@ zF0R~7UQ`c~+qW;86fU&&_4_jd#UWG!3iy`h_uy)o|EJy5)Cm6!vSzp9?OU!F=O>S< zsuRI0w$iVYrL^>oRn;8e)2#K-zdwJvBNKMf(bm`v=f8R_DIx)aysMQ(!Fany80k2Y zF5WOXi3w5koBaYBLP8WYoHVQye`aUdNPcPLqX(YG7DTjP9Pg&s6A{4>s3qKpiHT{D z_5qUsSL2JuCQzUQVui0_Ld!*Kx;Y_-j52n-X)v0n!iFO7ijJ;jcJ{i-IS`o8Ehi_! zzAK88GpE+(_lMgSv#o#1VVQaSIAnFzh>tIEYIUGuJsoU$P=%0va2rN%1mmh9XgA) zzgjRL&uG5mb6)rTz}}?cpk`PO=eXAt!|8Zz%1zZCn?MgeJ~{4SVFe}?CH}dC_^ZrN zZ~LHFdW%Tocx%oPdH)vF!!rGSa?Yr^8IcK{C^${aMVOf|tJqmS<-%}z@6nYmwcS|-ixlFk5|TW{MEV)p&sK77d(G=%e)pHcYm2MXOD~$n5a~A_<~MKl&ftyl(L}UK zz=LWWq~~Y)c4!`tp03fYc<*5UM-cx7_Zf@xCg?HlOg}&}hkxHqnz=h}+0&=oxT}^^QDImG%kJONQS;K`K$KU&Vjc7xk6$@#Ybh~*Cz;fcIun=0agEs)Xld+ zLi*och5u&;_|M_{|Jdj7?Oye*cu&wNgBkZZDm(N>ZU1uv~o zNm+4?V8zGB$6gHi1e8~$8J3a|(Fdj!Tb4u6NrSZ<gjg(_m`j-MgrZ%gYa|{cn!m z&UFC2dk6UFZ+_O-*C)rvi$rG-4v4u%ufD>*BR3Ni&;G(s-}+C}j{$SK83YiSi0B_2 zOo;%IFfd?akL+N8IN7~_Yh^hg0%+^(T`%+ogA@8QhA+w?K|xs0pHFF_8{U}R!K&u2 zyay?8qXildvjLufyGbqMzAV1gvz5OLeRC^CDWhunC5pL6&M948Vv?^V&u<;+3Ip5^ z0srT9I?liaO_k|H*416Inb1cyX#Q*dJ_!+0$5(2o%s)u(*|M;JMRX_x<~P{ozk`pGdsgR`&yF~iiBallJRfK)MjDAf%)W-nf=xbxXGz#X0Wvtf^}%~ zEd2sZmbOO+<4f}eH5Y5$D7K+RVeh=E!*p=8plb^r>qVChH zrgK0NAu$9dxLqNiV?O74hxNYZXr>euBGz4TQUNqa|z=a0`S>=mFeloH{Z4u*?#|`k~--1%9NMxygj!9iu=DA z?_lmpP+t&C%(;L6yZLmr|1%!#{zgI7;kXJ8@EEg!8b1a9KjXCCVa1!QD9G8$K`doN zo(k8DI1T z!?6l(Zf<7mbdlcsVvyYf*_FyLtE15B)91b;!bwbG4l%ko9@pwl@yOa*C*fZZBGi+> zBTC0^bJEwX!d4~m3IMLtnNa1u{`2|Q4Oe?*W)c#r*nPsh*9ZH(yq8@w>J@I&u@x3= zk?M60!(c78I&Mq+plV(TUTDlx;TWXjSqTjqw|vQ3uT9C#`?LdLMd|bOCP!Dete<>)+aM zJ=d5KR9DyPSZG)E0<-!&-0xLYHIB~Cq3l0Fc^(w>j6-*2y1{Wa;9*=yh_wCm)?{1- z1jh$?!5cvsphRe#ho|T9)+7No0ogBHRw0EC_S4n2L#9@D_#hq*!muYN#w4P-(qM2h z3;{vRp4UJW@F#y5W{-pw*28?@_mYDCk6cJt+{#AH z8y{2@6N^)R3@a13!znO8E^O_()*%P)-5GgQiVBxVhGcxY5S1*fM2PtF&c41vPnARQ z2;2xZRrAk+RH^{4LcX#qMCBZVIWG=kNMq!HCB z#hRi0@KUGq;hW7CxqnMbN8Mpae82fr$&t@6;duNN4L!++UK5ILaamY2xNQCgmDe0<3=xn?)(@evJH+fh)Q0{GT5W`w$ckyQV@jW5EJ(n zco)?nuH8m9l!~ci9xBQE`jk-s@ro$)QVHx}?h(P(eycT0mkzx}+5lq(!==o1qzU&c^$B&gXp2d2{}NpT5C>`Nnna zYwxw!UW=NKuak@yXeuB(U0ddZxq=~j1^g4;a$7LNvUB)X1fFaXpU-*CNzf2U5_9<= zF08Ai-u%z&_IeI-j za;m-HJfL{S=QZdUMEJv$F6hKD)JPJizT5$FzJp7qyN5@(3h@ZsK@LpfZUs??Oua*0N9CIgvy-b6sYsc8P#hZ5vWcWSt&2E)C!_DZ6bLM$*WzYU&Vy5%`WoVQO!>gN9 z#wN+)&OUpcHNnfO4>+H%JusUX2ao0_PUCY4QBlkbW%uM89x&sa9U82Fi$eE10Xqa9 z7+;Yf+;{dj1rPi*7=rFium`pvu$HU0_7c(PvqfRnlhgzR3!i}jz8FoGURD;J!-}uU zOiksVd?R;-)rps9fELK-b-8-tc1LJkLH(oS~(U;)$ zOPo8eSLZ8mjQ?XF47vheH?Ej>B@HAPM6xUZZ@S3EOZiu3v4xVEfYz_e!$dx3q9j94 zJjP~4N~J+NT}}l91NNMLy1=M<9Bpl7by7AZIKNswAe0#zp!rx;>*>f2K zu(9Zhou9fDi2ZpF&b(6Ff!ea5w(1IJRW-HjN?}Uyr#EdM+`!fhbSP78Z&;SOZ){Sw z#fbSH{Zt+}E1umW!QoUPCc$`;Ux$yw<<8wc1o>bQVG(t?9Hipm#VC-EBCat(2F}&_ z-0N59d1p4{iS6wX(n=ARqeHWW;L?KSwX& z{uQiWmm(m8`lPdP{Qb?80{g#IF(Ngde#(8hSr0(rX98dF?FGBPg|+ozPyG*U-9!y8 zTiI@ERi%4+W4hU*E3r?@uYY9Za67ig>?^etCwp$otWz)(gmOyHX2@HEGiTQ33|6Xu zBmoIfU+B--eb7WdZ>M)IEz*k1GaA*e%|N+9Q|~x>s!5|?*;}K#2YFbj)ezD`;KGGB z$#eJ_y*7`n=#J}GFA^vRfBo8vSz@`GU*^1;ZHJI?ba23VbgMQ`)&7WXn|=6D=|jW^ znAmsT+5{&=>%rl^JpGZr(!3-$x!WJ?S$!<*>`n#@ACV3{`=!eLnwW70?tz-&duhxR zcM2@;>!~t7dJK>`8EPHGHPcMFzAZe7RW_p~DtOalbBT_7A$oO=QdJwbK(H~RaMc9# zHC3W^a=uQ4!5)@+bD2)W`{($0ZLCsp#*?@b>xtUD{yN&`V7k49jWlo)(onujK=AF4 zaZUr3H(z1jr*N~U#>Sgtk&B+HfqFcWZfo!HV^uF-hJqEEK&L9wy3fgO^s5~BF3<>e z>z$XoV?46}S(Iq`F-gDOFV(~VUrf(h;;%tRrNfbV4hG3I6o(W7(Hq+PMY|Xgb4*H1 ztjczE>CsYO&Oph6-wYumNrU&NK63BFUE5%$DZJ~%xZ>Tfva+(-byxfBPj#t5gC;sx zOJY6krJ?u!4=_o*$FaRUl8>Z@irmb3cf~T?uQ?_n@fcfiSAC4Q!Q{F*EZpG0ale(` z7C)Bv48mNvxN<^aQ9xJ=h8Bm@VVcw6Z6rCzzTGY?ag zkGxI{gRO?~n|(=shNY0#-U~T9TjC%uB<6@Fzhbs_EtxJ{W=I1z4oJDCHVMK zZpTast##Vg#ooJ{jSYqQg7c-Nsc=N~0l?L5?Z2#adlMfy9dE?!tasrJ-rjzgYn|GE6W;eZem_Q{rZhQ51ag4SeOT^CVh}-7pmVnA>NafwuMlp^KP`%Ui+b{GM zMwFHcr1w5HpIKXzFyH=|ScmQXD4Ps!WnNu&t8GA6wm!P~gj(>%$*cn-{-sZm2Cb)I23PyBO7KtA++h;0+!R@1*81G9`&r3?L6uubwBm_XTW+dq+lekDmrz z;|7b4hlJs6TLP-dmC3#*a`WcA;Q0>vU%$1wo=y#1xvZ5DRLaN)5@arbT78!&Z&lh@Sw4l;CHL z2PeYT*ByfEs#ZtJBnjQa5)*S(F)Y4nUo&pPnQe|^m|^7upL#hkp!|?759*cK2DV@u2+BU3 zORXtJDSixxRU}XTC3wLRlaNqizSEja#m!x7m9AB4Rk3^D+CBh|{AICPr&)ffRqOqU zeZR4>@x>9PE!pFP%R(NT(yFSd57+*EWp#gBUKe;TZfdn{KY#v`03n=8(-w+jdnE;h zYCl8g@yGs1C8cB$+rX36ChREOLnqytamcA%>l=w+b#NISuOzH2-p$00W#$_Wc6DLF zE$|?J+HE8sEh@7nSx}dyMxxekkLi?Pc&O)n)IM}~%a9?f=`P$Uylu)piU6P0M?&B; zTc1o7Jrjq9wXqHen`RZMAeh&$uN!^q&yCNiq(qYyd29uId(e@xX@B0tBqAhH#F_y= z-?#xx?bT^B*O{LWSMhA}w?D9WYO4DeVVWK?i?Vu6X9P3J2EPpq;mGcM=cjm7vd)@# zhM0))WbdfiPy7VDv?%*!$Dk(#eBfMhvsZ3&E3r3<&Cf~@-CKDA3~7*p zJrd)@%g!1EDwmIchXIrZu2Vo7qM+Vf?{0wQ`m9U7`EEtnueJVM zT{tHBy4P#oa6~Ol{Rq;8|FAGrVAd9mtv$?(NK*qxp1b^aLA)M@w~v7gfZYdkzo_+B zKt%+xFA3KptpOhWctPtm7>Y)5q?x3`*oxc!X8MJH{y~RYfU48Im9{K$F^V_#?b$!cAI3)=Quk%@|uNj~BwO z=}U#AQ?(}uXV%zX2!4H$s&lW(rTCWJUVnCzR2}>vg6#00Z{P0JeZd?Z=INHtkt(vI z$u3^JxO(b5gulHYcW!KB*OtzNnU-#2weBV3U!fM%2Tn~MU=e)f$GYQwy<8rc_*O&L zr>*tOPW}NQm`a9sa#NEce8iPr9*m!PN=Ep%krHKrO_JoWrTQu8ZvV(7T0`U&(n+Rs ztNmwh;W)UX+5Q;YSVez2MQ)WnaQZhRA|f~sWMME0%$0nY_FQ|Pnpx)h+~I!WENXeC z^>=AfL}H@P|Kocwpppi_ltH%}=;FyRH!||wx!+&t#0At7{Z zm(QN+Hoa)wg>X?eQHC1bDYqHN;kwfTt7@|rMjurnOkSV*NW{iAeTU5#ST#LD^zc-V z>Ju@ovBxBQt>3<=aZ)?9nBnDe`c-RU=qp1YA!r2F2C~X6r*}TsSNMF+{SxX zq4_{%mYn|N`EsLHz~tvtMHK<+i?Qc<0Y8#?^uELw9wMa z2m50{U%i8?8F%_`X{d8aO8Tu1_hB$*diOa1E*cvaux}U-kpb;R;>&*7K1V%9$;A{> ziY>dFR=pTCs@3W8<0BGxsz3kp(KU^YXn`Ef$km!0O>QMc-y91kXIi(-8KTwcq$EI zm#EF)e2tf1mJbIXqtVt}FtLAXJJp-in}4_4+jGs1N=avT8SWIIcj}S_Sp@~l5%H*C zu-v<6wVjui7SZGwtI&^8i^1W(&WDGaef@%o9RkHjPrpx0;AEqbr*m@Tq0MvgM?LLd z$ue?irSLqNO$fA>D@{|y+_%w6PD;w~0h#S*2iw}6>#Tvy<1L3d?= zh|v$oWu3MPY58pby|nd!x9{E=6na~#SX}VE_v|=7UJ_Rj3Z&t}7^hrax7NtTw&;AT zU*FU${KNiyg0@OzO|CMnRNla8`;|bs^xuE!zZllJPBqGjbm?eo2h)j8=H$!jgY4n% zsxEm~l9{==shJsj6q1RF>EcCsh{Lkj`*suK<-R_bj|E#}+R|0!3=Ga4kvt$|L=O*I zUYb5_$Gyllwz2VE|CP-A3$wy*%>p$G2afzsznl3-aaD4TXyE{AH!Zth-aAP#oN4 z{0(=&_Jg_F$-zMxfvA4{`V3>^;NakBef?;C>ccZiF!$rNcU1Uq{69wjF%YU>LZvNX z-Cy$YTX>nd&UT9q?4UAqjrEIAG?~2_`YTUy;{(P(5n#ZqB_&o)mg*FHO zj~^G99$nI}abo7p$8lTZo-mf%4WSu5X5ajcv;_8Ffjk5T^4?R)CQsr$%Po8IJhra= zsAXmq9qGdMbJxX}AKO{xYdOq^7=o#(OD(zf59R+>`JY@e1}Z8BDz~|9b{ZNQ-h9~* zMFCqI8>`*|7YB!eJ0LD0rzrR2iIS4Mq9QS%Vz7}dWJ+^&?-!Dcg9jc0+Gbp>4?*Rh0J@)AA}~dZ6Wn1Ac!O`LjE8hprsTP+$&x7?epLO zBve9T&BJs?A20gPW%@`{kFQqW2L~I+j_GP?4aZ&uLdM_2@+7|e+2V>GbXtX3MNh$U zD9Loo?SQMR;j(=CgE`L3<)FwM&qYCeqjYHn22+23nM#_Q*UrgJj-~y6?s%{$(u}pu zxd|;I?}t1w%SR5_<&o~*_DC{{^*_FVETrGhdlsoWafuGhy{&C+nP^MO$}qDlqp31& zU3J$_M*2JEJ1O`3PEW;e@n^NuZ@uNr5(2o93cx+!Y4s_A?W>50NQ)^y;%$(8;yFp~ zIQ(=q^czqQIZ2U(94U<7p_fH%p&gwlw4tkZ_b%e6;Kcj)_-B&P~WPH<~L576ly3pYO*Y?8;%y1|R!?8KJ?)<@hAS{?B3y z6@+5zQ0byuZnXt;>(0(n zVM;2xD?TIGei&i9%g?{97i%`;Mk8oBUMW#*CCc~6);rPLtP+mWQqvFU&&Ev~+b8|dAJl@(L*|4bMxoGYY0iNHW z7QQy-MS z=nc_Y*ggJCkO2ei-VtApGyVAsn2iAQs~_suPu0up{0ka-oBjZX_70f5el0bL0SUjz z$odLefkdmN>Px(A3-4r+?7GE|LZ}<|9zFSZ$MNWEx93_`=lJ)RhH+eif`a_~saaM6 zR)d@Vjb{tnbKs`3cp&Eddxk;K@^{H#9Nf&!thdo8Uz{M8E)P8SMx1fEMa)tE!4QfG z&ukSWM1_`^WbumwLa<@Qy*jG{NNaF0K!*(v4~M4?K727PriudAok@4?o3`2Cy^CY` zM00=p!0`kDG>;QAQ&VYFFVHNVeWU$LOFO;{;SYVsX@dpA&G?5zvAtd%ykiWli3aCG z!H_zb{=AW?rm{oWI&U1jVsP!GK-~T^6U19Lb=jcGlUeBYTQUloLmgTU-C`of4Bmz$ zq2D`B%tRb-F0JLGn;yhcMyX$-9V~b2Vz}z9*^L{ROr7}qw*HFmAs}TZe`qniYtcEWhIGgE*w)#4Y%eh4<^TNogWGAe z_wkPF%Th7<^-0P1*d_6RCOG&>hGOD(zfr&SKPPa6C;L;$-UNJ|=t`|+fAu*=Q=BFf zSRj8s>GQ9tdHw5d4xO(%f*|OWY%<9{w4cLwuix=UY%HjJ zdwJ#%UaF?t)~A`0Vq#Tf%RA;QWhCS@o3jhg=#~vPs;jAklkc4B?0PRQ_T1SiX1IKS zHoPu)Tj<%z5w@>66e#V0bUXEAOh8EV++HcQ=*k0;_DLJa-Dqj)h!{Z;Q9kAfdT;5w zO^v0?8umj)W6-FFV+3;Kf?t|j!~QK(!1Q&h(6fkNuGVt~(?p%ENNas@$)Y=!tha?8 zi>60r4xz&!V85ppPPpz#Ew?(%lkB(4Y&c$LANo%|3B(Z%58RzUlMMtIRJQo64hCg~ ztvR2Xo}?b8ij?7c_@lFPyuSVeZ*%hx%LKFQ8H#jJEKe-=WHR7u5T??N_PT@m+v?uIH`VJdD`1U%O#`njq+owxfnckR)qu%w_ z!ISHfvhy~ingf-H<{yES)`2x4O{_Q&bJ4Hy92zK3Q(%cd8Y@Xj_H|udqV%o(Gc5%pIXj2^>c68(&tB`Rw ztJlf3Un1*~>#j9T0b5jSskH`}e~?^X4+kHD=g+Be-Jf1EkOClh2zdlZxEsuC@q2k) zfKxZ-lNp=&#UA zco%4J&%-N#))cQzoO54(nkB*Lh{(O6t z7`h>I7op2uthOxHZEk8~6UOqRsR=SMaACP2>S{9|Ny$L_S6yyl` z1nw4>ma0iwTWWvZkndc+Yj74@o!}k;{oU~J6kntkDHl7t%JkLzwbRwpTpv|DG&?^x zC*k+~maohrlxz4hmtsW9ofYoWOZmgi8u;m!jUMjH+eFeR_kC*#xeRaO#GW~-N_ZYGc#jTbdRpv@pktn^%(aW*n3iG;txDD1? zGTJW{Gn(8+0tJ7bCd&JIxL;j67aJD#$!8W~O9IFdwi_0N8JgHOV@II1qweVZ^zU`# zG6#OD$5K2deAh3Ko8Y!Ly8t{K+2JulrQ`q*$|FZWQgg6N^Xb?%+D!7`*{^(>GT=gJ z9Dn^~*j=XYWo=D2QZ8uU{TpIE*$2SB)(`li>(CqD@GoRhaH82PP8C}y#_ayR6#`~y+m(duvU6)|*e}{uNxYZw zo5divkZN`5c)J+rN#qEa7paXEQZ#8KZ!5Y|7rQ;~HHM4%J13$PiBt#1oqyMcii%2* zZxX|mEgjk^Nk949{ue*_pS{4$%&M!SbN|^Nc4=ySmD@F5gRJff#)uX$Bf4obNkMZZ zB5Ehq)s{*vw`CceVTegd$qiJIZrGu&J$HrJO$mkzJFI?h>H&|uVa;g9jkW%sp7XjL6 z9zH!SjcD|Qn@zm1^Ci5hi9WBcuBZe6OeM``8z%=_Z^=+NdO$R&X6^5{6(O`STt7(M z^JTHb`_0|ma#|#x*ogg&k9n=-eSJ=^p1?(&0cBOEm&qw@-Bb~fX=GH$$LCG|Y%C*J zR+$m~b9NKvd>}c)*jDWt7zA7Oe@Rzn19A{#bwE&Ms(u@LfDVJ;o$0-2o1?wduLbc{ED)B&h=RcsGfZ!hL_&=e7?~n}SSp)x#+CU5a(to(*|M}wdIsKof z@&ETBgnZ7XAy78pk5#zEe)OahasUiUeT1F>iFx;q$WVhLa)0w^Q?CQ^elzXb1TdW& zZ-N{Wb%l^ac{P|CL@F2fyepLIB;Y`XZ+k&4V3i>0mc)yN{yGpSW-Eq2$jDbdU#yRb zFMSrk2Aq9+qW_&5?0y(Z95yQ-;|8ioS;a%bLyMM+;ayA(^)TG}?~&ahbQmWjfqF7j2--wfXfwU%fo$kYj57oyWumNMpcYD3t$)FKiHu160 zgyi=rIDO~pSxUBmSZEevVvCENtIAdh8R3)aK;mHB$7`aua1+=>u|kf<;0%2)1djX4 zDk%2*6Um%*hWiZr@f5VQdX%K641RY`*lLj>v6!L8d{(>Bf^H!CWsev?jr=`ncxj^4 zImQ*){bytx5F4-am#%9G|D8T^zo_mQ+S-1jC%fz)^=FGkl7x<=T_Bq4FqHfea(#kIRDC^0c{e-j9$ z(9Fsz))}YSwm!uynzEKY@%vcy-Ty@V?rxSCktYQWP0m&?R@4`}Wt0qldLLus$PwPv zK5#2v?eVp(wohd?valPgf)m8NV0Hy4!NXv6v#umj5M%3ytc}>iyuUpb#@dOANHM)- zuiyp~p#LwEC=R}EFyDaNOssOdqjMR$1=JAO*r0E;vsYM0#jSIjc7G~}*Pm1&yXxfl z@S-Fz%leNC4=*Qr8P2qAxvh*AJ|9v&Nmnqx=QQ)P)tVVz#W&qE56>az!OtEP_UGCJ z5);thpY~CwmjK1UTbP#@yB^+fu*@L#{LVeDNZvhox-H!pTnfgQ$j+}zLS-CH1^eF`e0{yV`GE48UtE3s`_6qc7`f#?PVMNLi3c$CBSUEPbUv+f5 zo6&`PzL4o%;XKd@j7Smetth1ZL}f<|a90F<=AMhMW=48?c$5OU5qPJ=Jf*8Pt5eg{ zCey~p$H(^LmD(#)Z6oEj_H#Y&$(-7-V69+sBVfZ8JCb9;s|3v-`8N3&UT&P_Llvxx zn;Z7eND91B=pzIN2LqJ@)+Ja6x`N{+bi$7Ja!qHwk;9r>8@n4|W(hpUyxA{PU$e62 z;mOxHOuqX5=8{I*8(3kVF1#X+jPv|<+NsQrLvhfFJzF2-GvVgu_J1869i5bvG&YWn zj)^I^+{%Dn!y>IwdY)#N0gS*waY-2h%{mZnasSl}LjrZ>?i*81M{NGRcEWG7Jfbi8MQK!NOw7QGlQRee;u^2Ejgg&7NI;B#Rn=iH zyV^*(b-r%_$b16?ygZn~#5e=2l+gl5DHsAEr*i)RpV`~{eD}+ckHiWS?Q>`69_^u~ zCiCsAZp6aW(D3km+uzS0;Qs;gGRRs2=cvwXKb+&mKgkq~jh&r#!@ZW`UfU>1t)3Q) zdYi^{bMQok^*qdp0hzaLVr6M348rENl=4eewd_cQ_Ayhf2-II5`1k=J2B-2sS5(a7 z_Y7Pcyo#54JiOV%77Y^d_e+1KPr^35Z#Q`T3XNJ(0M+S)Aqz`@A${w}$Vf}KoYG|? zY(2~o@#y_hd#Ng7xAK)QEofBsS3`rzbU-jnT=DA0w`KTL?Q&{<;o{KVIKR#C>sRq4 zF26Z5J$CMv~sn`XlPcd=vpvuVN;w|_(nn#x-VD<*dVWibS zUXAOHPRbS4kr+d7?dJ5(6?_LA8Js3T`!wn~r|(^v3*xQ7yiO-Vn3-9o>feSt#TFgc zRFNoDZ&HmH#C1?Rz;%Xo1^CSU`SXBqfBp4kU=_in%I7UvaEM!Cp9MnpqZ2U-7%fUp zwzsezfc}xvc|T)o>zwf+Rr6*gS_UvBHcSGu(@_uSwu&?eLgIaDfp~E|5U{~>l#5re z3rL(mUrHuDZ2$ec=t=zjSt~b7_uf6N8mlM;^Ts+ckIk7DHCAxI+??HqSo$RX9-Xl9 z?K)ghX6F1Tz9aFz4{*Xfd9;8Xd9Xv=TnF|F5~O|{F>PC=61KY9+PT^_8L*I!^^Y=^)XRWa1J%n0C6;;!nUr*$zSN+`aIDZ+=^T6yoJ5`wa3kw~(_wA2ua}X(i3kinD42N@1IrVY;Wd zDP+JOzGWLKizJhrNNX)F=i$fR{v-@0hTDf7INwGdPQK;)k@fS{hu(-IrHg(P2D@v0 zx`(ofA}-m>Ix)P-63z!PJ9W=O$u1HT$BA^@(cQS6dAlo4T>hig%Ia#3b90`H^?(bu ze{6WTvP5%vxRf*5gOCxX9*$ia@`r}4(-ukWN70)F4FQ*EqDNhtggH#p}U zz<;T4o9l?9@*3L0Cnobb2P8%Q&QeJOHs|K-6@0>AiATixKRSQ>x(pW-9Gso4$Ff}t z_i}GiZb!~_#vghj*`FV@FT$(2$lF)mj3GT z-niTI=QC|}b~td4rV`2Dy}j^my*t;h?t~<5KW7kF@hR1oJuK;}&FvQuZ~xI$0FJMu zRXdwepcvz4lQ$u4(L7bSi66i&r2~d7G7yX**8NnTNe)B?35-O@hgf9@ws=koCs;Ugi$+jT=TEEiC5s z+JreokV0mbmh9fsAg`sq>PzDi!(&KMdyY2~rgK%&9__65xPf!7tE+3hl ziR^>9WJqO$d6N(K5)KRt10V$oisA9aeSd=vi{|FA7fJ{q_C$I@`#eF|*%KGjKy>O^ z3a2gUrAs`0l-Xla(3fUQvAT{DqI|@bEO!+I0aJ|5EwYoOB%qq&v9b9I^^o#20R)DW5=F=e!+>BaEa^MteqrJg9L%-@ zWr+tve;MW7w>UVgrsslz%h+GB5PQcsm`rsga@L7w+tgvnut_bWy6%WnObp$%QEorc zZzz20)+=6Md1z^CTbM44^U0DRcOn&&g>&l=FNRTUZi0Ki&qoRFoCZ5o#HZBV!Ur3- z)RMx&s5XU0um)?>ta`EtiJ0a)ByELUtSKZ?*O^%($S^2of$8>OX4Tlja0M%)jDmu> z_h8Ht+x|09fG=9>qng^?s6rxZ8!jW}_b5d0`?u1F+p4l0%&O5*kBK-_&>!mUXmWjN zTJgM(ghH|`J_(A9jPBG`*^LdSn#aO{dNHVSccoj+WSUUCy`xgZ< z=;?%0W>}kret!^7y)BIpif+9v+xwA;tARW~ zEjufatd$*wifx;l!x)f-Fzs{jB$F{q;l#o_R1jJrWFc1_BKgrp=t(wcLIsACWB9Ba zl`&|(QdI26tS{{f9o*V#&P}7gf0hOO9*r(7iq!g8z;caW{-P`g6N!&-qk^WyB<{M} zpuQA)?i!!@QVB-JHbjxIuz+oP*B>UW^YtIu(ln-;SD-?0Xxubw2!o{KXlv_mxzAy! z^lNE)7d)s3Jxt{^2QWH0YX@FhaR zxueMzcp|RA5oeUFT3BRIJ-h75U)`{fEW*7_6Tr z2z+WIOjVD@jHaDbXgb$o-37DDD*=&!5vpx6Yu4Y_Cz72Fjvk|34@_WB| z2VatdG+*2+#_MgpM&jC$pbAR=*U6Fdn@@7c;l|q2(-R8JwDtK z?4|24z_M`)M;np$1^muF%Dm0%z9X+1u&zwU03_uHazIwfLU9B*ppDeeom<>nGfx`q z+Lw&v++s_Qywj`Iq*AYpMER$nDWX24kuahiNK$Bx*qXy*(n^Ikvm??9q+Y}R$g5BG z(|*lKTlGUpW76cq2jzOQ0A=KL1SZliXS+|~T55ZT(bnc;bJ<#?40|&lN#@k`^bgr= z@LsZruM;uSs(mtLXAEWhBxx=K~&oLF7a8|^_x*h`LQWtU`n1;txs%a%~!dt&Pl3;K&All5q)p= zX4(t|3|J!6A94oWahiENx#b2!68*NiFn5zK!J9w^6%{FtT+gSXST2G!%6nJFN@q6r zO-9OQ@&|>3rI^no&e7S^e^(q)_*u#jGNe!xKj&Rmp?j;lq@7q1y^yAwfGM>a6e06vz z6rZ?bb^D_`HFj!>-+cRetvA?5VKaO+iAJ?iGVci-h&G zdacq(RqCTEe@Qg2GU5gzR#k$hRT+Mh`KyxC(L^N1N2k^>(3 z`#(baOL$RJ?;L6CJ%6rhY;11j>1u9nrI1^{aeWhj;2pX{%}`aFlQrXzr!XKaD1wabLMe$(^*na2r zU`#SaT()=QpRe_5@~yPogMWF z4VjT&j8Z!jkA3z{K>r~%JN8=n>Zf-)&rr#0`491FJh^bHy?Eo#sSOBW&7k6aD8niOzDKitkw@v&{f#JXE~e>J6N>3+ z)el#GtEm?A-*t8_qIB|jS^Yp;`5Su_szrse*#XTQiI-wGx_IWChpMomxE)i=JeiZbWsKhhm555WB7fK+@t&W$kuT0 zrV$=6qS@KmDWk8<5p}YDd>N=bpPg;m-(6uf7_(l%rAjPe{Al#eS(Os6wyM>}tLA8M zi$@VL3Rw3anXa?ew?SQOi4t;M`KU}UYHp(vJaGMPM$g^Sli2&YK`VL(N5#fv!n0V?#SdfSNbabyz#d64ja{?uFh2z-H$;@zBT!zIJu5(4=YUs3w~h3ZwHrVp&;g zQg28o%PjT}2Pe#QS@QlX1Su#UDyN`+IPQB?aAl^xM>BHCv$Yj`K^tjv7~Q4_Fk)k6 zL?JL}?8;L@W;C06g6a?UsMdcyd<|UfG@xFz(y=nOLKv&+*&J=ntB{jVDmC0fNF`l3 z_Xr&zEk+vbNqvp-BqcI^Q9(3 zK`TEmpV=i!Bl^dno?m-Br@JZwqpxkzT%27>jTZ?Cg&fui3;`$Z@9)qRbzRUxRjzMt z>Qs5=lI3+Cd-2@jN2GNE>%#v)A zaMtHC&q)G+W~I5cy*;|Vd>-aMH>R8X1ox{pC(3PL`*b7;9HzZwu=JLC$WHgm?;E6n zxEP4Aody-oOZOy^?H?nNkZm?zzLgh!{s0qzDQ=;Nj4*`dNM^hqDjIw@{nmE=FFK$ zj*5gir%0v*$e$gL+Py-UNTk@)kDAq@%^-ReP(+)twaGDarBg&l@sl(>)(SAY5uJ{{ z!zD$OPLdwUNb-oV8S~h;R*XetPR8~Aqw4`?*INr{<>Zm-bF=0apKEI0`Ro+i9+qA9 z^!paW`aa%awv}@AoVuX>*yv}=E50Vu@IY$3cIn03|7`Yg0uP(E86H=e&5#oSpy)1D zzvJVWgAcXUFnbrpscCm;OM`cUlV7*gY6n<3GSadfSBbqu51|0rT^k#@DS5ToaoJaU z9%yzW<1u7YD=XD@tCgTa1_!FR&%r%z?k7JmP~IdaT9?}Pm z;I29ugkxoUN+zSC!aqJ<7i&-hGqJ#lOHQ7cZVm;oU78Tk#*+C^ak!%am~sa7FB@Cy z605$0nmnv!^^ftq-m1^m5pA=Qop{HAPW__`2X*3FfkjMeT91$07ZezOg=g%qT z?(1{7q0IwmKh$Njb@oH3QMEWhxA8X&zV6T%`Z##qA2B(z&m{sVP{jGxpwujmIg?zdL#v9Oma--&lWRw_MfePvgg0@J_Ic?2$wKI zDog0-?7Tcsj(z$1g1{1B3<}8-K9fop_dV7r-p%wVz419%ypu?!S7o<4$y8acTe0l7 z2WlXO>(l?9q-#p?<_E+j|AbWlbXzfpKi@Wwl+j_Z7A$)*pX}SU{(1O%pJ`{gZ$NTX zlAqtHwS;~6&}1{upsLblzX(96bza?4o4#x_&R`MPwqF+Bk-eHIJMRBpen#?U$M4@x zFmqnIjGNekE`&mtOeAs^u-kI`5jztTDMG&c_vtrV$Tr`Zm%hGmxy))TFj-TrJTC|M z+6PJZ&90E&;5%8~Xp7;Q_d5%GW&65)4GZW-d^xQlFQ@0+quhveT^a4J*4~0l@zDKn zeNlg8<4UvJabb=acfRcZ>nlksCnp1VumcKgsbz{q)av$3RPri5w^d-;p7t5fhp!y(rt zi$l9d7%!CbuHXN10i-fQihJ8tZ$+qts9_?dc{0zPEBW+71?n9Vs1d^Ne37n4Lj2H< z<|i>@OXo7Wj=T|Vqy+~Qq)3mMWmWqhH?`h=Ux+epETTYS5ZYle@yWm@i;V>iQBs^n zSPZWbb7T=joew(6-X9XmOx zAK}GB%$6dJ-4492ZP?5#ghR8$CFx1mW5WW6?;p(M*Ty*YCNx;?TK(z%G&mR42(jVO zds;`(6BBoVf##F_nB<9SkDi-uTz6kfrvLi&t3{0^835ZX;`saaI=C%_(F?;^^}lT< zWs1}V6-IAXDNhP{LV0$x8)++}_3CdfvR2kD`F}!3JZAoas*i0Uw&7OSd#Rev71p*T zY}L~^pSY24`zqxYx~;RNrS+#0GRoq1goTQBEc+0j<2@$KO`ed?ne!QDY!{uPDk>k zDZ|$u4{n&)j+EGf2o7LII;B=Evzw54Hiy#hk5%|gACRt+8xHe;RSo|8>rOzjmwH>q z#sHueVG&_jm;3X7w(1`pDQ(sOkl|+h%pg<|^E$;5x7PqFj zLn$u7NwAQ+=sy2@pYF>&5BKFfkO5m5xP=NWZpK{EcnITM3+=djhZp+-uQ;Y-?2Mtsa8&D}Ja}!MhPCPj&(K-G1(@kBa zkHQA}mDwEn2ZSj-(nA}{xJ7=8Kp=ykZQ!4>Rni_kT=!vn-msD)9pV>k(|mcDyNDnQ zh;xY7A}i8{hNbNvS(*k*8xV8XJ1-vmD`99yR@S;Uvm$nSpGmF2`PntC`{|L(FX!S})!|ZxmeICDBUAj$@=*h`Q8m*<&U&%*Vfb^%g7XRiwGk6bi_rf8ef2eusH>m)Am@7o>JgL zTs_eP4~TXfNxd?vWz09WNEjtLpd7BBYkPav)}{u*BoYU0Axsr%&CuUBu$B=bP=o!E z{wa~~TrREfh?T%O`4!vmCxon;SQfXUm(z@xUs{;aEPYV zjJMq+Pg`yI21O*kqfOmEHzvIZ8FC{h@=T2W)s@uuifb%dWmskFR1Po!3hYZ+sV|9SZJ)8GWp1Xga5z~yCNCVFtet8k=UT<0u(TbW-bK`DKQ zRp@*9&RW(~Asnt4!cz6{WH?cby2Uo5D_M0>TI@aEm`~=6nxKa1M$oh$aEb$*YNjp{ zaTaLYb7sa#23#H^gQfWXx>Epp41&Hpn)ngR-zsjm?MNg|Oa`o>w z7Pg8gi;&x_<`NTI5I$D=Py6|$3s{Lza=rX_sdpH}g{SEDZ9}SzD#ZJE^zyxebAZbcsT5Lmk1=xolqYt7MrnT?oBmr8d+{%*EQ8U!_`H zgwmRpIJ@_gdJ9{eNUrQ`UDw3V_c4+9&S{wWiEIB4oD|bUjxbPK=JIq|Z9`lA*SC7E zquNQ+#1u_U(4G4^eS(W8`J$9P_P)IS=v|Llq|cZy3ooz7$Vw`J8c5iZ7WW^XCvd)f zz`a@ZNxz@eJh%5=&-UWoPcVykb2`N$0W-cCdgGqbR+6>X>PzmfA0F{OOw|{nXVaN& zcp@D0sVhMV5>CWA=|;t*I`!(hNnd2hgkJr^&Y!Kf22FyRe-9qY`KQ-^&9gYS&#|(B6N=wfkKH%C>i>DqAgk zR8QKrPnUZb2BO7L`#)|U!R@B2Xu|7AFlPv~e@{;|*01B8B5=j>KiOT52Z{6JDNDS7 zYU4JHw}Pt6F0f{T6(}WgfN^iHSoJA7H6Q21hv>8AgW%2X4ftCoz!9e#NeNe&&9KPN+TI59J>-)^t%WGaP@(-*&g^ zoDs?5+ie%SZKqjBi@wWdCld&;mc)Du^cE^DFS1;T8P$TCtqzKGSX&R5!qCnjhk0}M z*ZO`(?5Y7xNL*Tk>&Im7<<^zLOw3O29n)Wkz+c%AtD4k;k1$f#bWTP{DMQ8=-BQOO z65bf~=N6$g+)!xABeKad$ptK@PQa8K-uFIFpz+s+8LPzO(=zf5LZDGmvoWv4XGb1x+J(wf5HB-O z>J>vKv~WVM>n>su89|}*>nZuo}ED$76hI(2v z7!bpM{bWXod{~8F%VUBsd3bp~TlbVo)Xu9+zhD5xJ>E<@#q<2`_3|-N67W(=m=Law zR&o$dkt}!;V<-AGTS_rhpVd&J*w>Iu^hr;w> zFgP2b&-_%GDb-{xT!tcBKJ+m>>V1m0o+9{K96Q{?qrL57d;SU=t|w0NwKX*#7-=LO zufF_%I*F1k-D0(2fPRpF#H<*)y+wilIn>dZGq%E)cO%(J)NtDfH&nj2lO?i~zqvD| zYs$%!#{!7kEv0(V)Ml7RwA_;|PxV|E<)4c92 zoPu~fT?~YvhkNEEVHaY~*kL$Fl{@H#g#AfK)L@eulv?og=V9~a8;M&Qi0omf1A|gY zS_-R42oJY!5yC=0eBa=h#&3es+vS=q(C*p z3Gu46^<&q3SN;%nTAO8|PL78<){hwRD+i>!+7V?R$?2T*K?u<4^hlvafoW9q>k|qs z{-Ow?7>kISZ3jjOF)bn9Lo(NBBDyS@KL@QwQ`c72IEGp3c9Z{fHU_Z$3wX4#YrRXi*T{SR?!* zM~&rfo1J@=PpSztp;FykGM4y^GRkG!8_+bkd}!aj2*&$izp}3#3HFyk!KOIl7Y%0Z zR};JGEJ5cxGnT{V_cFak zzdm~MDGyGiT~lv=_pp=02QwuRtU&&SE8!r2IEF8GSt1u*B)*myjCS@rbCI;-^@yep z14huIUcO1|7rBcJ13grd90o6#`CaDjHx~u9*BnU5RUdR&`7;q{NY!|xgcI=mn2A!F zH(MVy5{_eLtAkKI!?&iCAuCOF*&wObYMFMIxto;Zu*3gS;x5Dg1rhTbTwZqW;EpuzC^(7 zmVVq0Y1_t9+D_WUuAgLVitb?!}cF$Nb9knv@pF;Jf<7 z-NQd`<~nh)?FlY5Sthn*-Qskyr^k<Hhkw<7+^*$+VvSE=oSIfQA|*BDo;_sdQ$9HjGui^<>ON zo0{RUVMYzzZsYM=GM$|t;!|OSF;9~FKQ(Z~-17_2d_XqR?L~0^KWnMXw|0Ez-!SN( z=cn2D@98d%gTIVbihHGGz&qVOqx0V z<~M?v4aQXru+$7&@sYU(_}j=(dUPJ3H$<|T4PWHwM-bSUL%PC|@`FZ@>HF`CyK|Vk z2I=XgM0T5&szgv#*J}g^$Lv--G)F2_KU5(UoT5V1@QpYI+)KG$H*J~Fr-Y82c~9_T z;s^CygdkF#Y~A-_xb9Po81`7IG*16lEg@nQbip(ilLZl5vmpeU^3P0VB$aEwiUunD z37MYO4@Q|3nOM8>*v?xf%`9fCnXe#3p2JI_cI@2^GxQc8s;d7%&d66k(!GueaO`MP zLZZSUn(^F>bWof1Ngs`zT4Eq6bN0d~&{O(BYeCFNE8|o-!bZtLhi~IDo4+@OCuwqY zbsT>Kiocs811Ha%7(P+y%vKqU1(>(0T=~DgVc;N>FP+|j> zIZ78wyhlT*G{;z!vYHw6>${w>FBvAh(@r-$KHgZdQ8@MQj{e(qh)NqeXV+PFk0F4x z$XiN7)*=ekc5o4I7bc%i&s?r1zv*jiwH`;L8xDs;Zx^t%Jj=R%9GtQ25TViqZ=A@cyYi_l2RP;qL5p|J`u!3ZUfFeh*)I4DAH#5O2;@DX1Bm*;xvPXKF|;+l zKdHb$qLoXuPPMbZtJubc_PXu=MvU)VuZpDP=hZ4MvM#ul7P>2YpZ-*4bJGs9(GSu? zyPr#2DEx>@Ot4<7cf`-UKE!aog{6oW^p-VJQobxUn5|0m(VAE~t6QNFdNj z{{dbkQ1X<=D)hOj!NOeWf79%HN~>J%djg1?BC9?xyaHc9`GX8hA1Z`jloOZ!>~FmD zviy|3pr&T;Sc=}Nr+>hT$BMm6F1g&>c~5O1o52e*PCM+JSJm!FAMYQuDk)HFTbkpegVta# zvI)k&Zd_Bgb9p9VHZ4H_Od9e<%Rc+ly_}jDNO%@p$Wr`>dZcjZ(~@(OxAj;5cZ#zp zs?@y5>sH{fopar2GzGir=(fH(lR(UvI1cFJ=$3Odhy_Mba_r2utG>oHv zI{|0szgsm9PT<}D?4SO>{*s^Ulh?lY=5FfWa#P^IlD>Y7wg1t(xp4ir692z`{QqX_ z{?EVv?~m~R-G@wE8wFp7{zsKK|3&WaG{*^Ks_@!g`+r8fL8Te@|9RK{XctfaN4xlc zegSLo|L0Cn{nAK*Q_(&$GV;%xqV^SEF_(|_3n&~e4)~0}l-U_P?aA`&7pTIO4AsZ!UL779*YL$(cD>&DzZ|MLNX^Yz91g z+kRiw3z$=2(Yx5 zhb9;25D|kH{tHBUro+#XU>kqk{r1a0C&2jX=g)qQ=g)=KHY{P!2_nVNa~{_XjrJ-D zY^S?02|(5Yrb(%{7^ngT_$*8xMc=?AQZJ@0qb2JC&kon@o`Hw|ruNT=;O`54Kl|HI zDUO+GhgKITWNI^ebks=aveMlbj`Cte_WzMfw<0t>tP2wE4+2R3K#qmC*XKts@6 zE?mF5nqy|lbUzvrw6(P+9R7CWCPE1FQ4f3IFeHj|kf42lX%^QN z?S%142A*%`hnx+VF&+)Fw_}h#i$V1ktKp2!tT`~*Y+xQ-h}^m0U1;AK8E84YynV#| zS0H#B2n6k(TMo|dwFIH(eVC$+eV1hV9xEF*jjD>WpBYdG?F^Hc`B!$gauRs|*+XD4 zZ5Mk-rg^!!X8xPGDwEe}%InNWw}_@h_gb+FBe_bg?f@?O{O-FUpG^jr`CGlHp5^lP z1ONFGvx`Yb;Qf5u&y?}XBJ7UaN2jhk@(m`l`Uhc!_qV`RxM^-=WwPV|& z&XI?+M8w2VLN-wJ?mV8z#us*AB0N`f09?OLFOLxQ&a)HWQUPQdP0jCbwbTnP*}x?K z+Smc;VL=Wo{o>5H#|?$1!>@Ij7Xe}=)^h#Etc8=r+6nOaSLW>!g8|odVVq@ZgA+i> zSnx4Tub}2&CV-S+we?W~P-G!6fxEVuLB!ELVZdGl*=KJ$1hOzY~ zkp-WPC!TP$UDn%TfsMv9$hpIUo}Q^!u4d6I=+bFyH+plFiHT`FR!y?;NX=&gwLmTI z|B;PS*lDVwEX)(ggn_1I6!++61FmxkFY^DP zt8!cZaQh+gV1{_}a2Rggm%k*_yI{~93vbW?2h}b&HOZrI@R*qR@nx7!6C{v1^~7?v3%9%$Io6GS>nUn;F3~o2EE&DVswL?COD0wK$+Z$v|B(7p2Tn_*5|tbB{j8N1+-1$;OW)AU#r0BdvCEEyP2Qf=6AFfMjgD79W6PN z810F}_eTqo<&B(~7dq>XRTX1Cc?qWN2V63dgCaPheg9HRO_B%>MYT_}|J8_%J$`W; zl_DTwpo$64WC34~T3nO>_Wd&)pJQU&Fs@~L)79(gAx)!o$eAJ&0B#7XwpG?ugJB4C z?~esUQy2XXM>*NhUT|eri#+&5wro$puj&d)G?_duS z7hdfHNo1r^DtZWXh}dc3T}LI|j8QdF%)UgJT8oW^fq}ui-avnU(^b>97Rcw=>+Km- zd%Re07u!#i2s$70E(FdS*MD5>wj=Ncc=>jaKYaaDEi>gER*2o>}ZMev}yzx4mG6H zwC(6(dhmF>p5JP!Yuj1ftm`a-id{`)GY9?IKk>!uUlO7 zURDtdm!~2TD_IA?ObIy_g+VWtn^w=%Av>uT>ws$xP4LDN;Pv=(t_O+l4GAt9SKCAu z&x4gJ8%-WGVPNZDdX5}w2WGsOb+f>Q2AaTfzH_ZZ|Cca3P$vzn^tmdphj7ZkS7C%| zVh0VCJ%0I7;;1QbIR6>$p`Ks2sV})+Zoh!_cZCnz!1-BdCX*TPv$8>m(H`ZyfCJb4MbeCPE?eD%gdC`eU^; zFHF}0dDemG?BrVz9_VpvtmGu9s21G4Y3qAnzf)o>~1|RugM;7%!S(QEoGLKYVyxlbYF%~}w#z5vtELxuJ?5o>72xYB8=emR7$|FC6PC$<$wpFoflvpL z%)frnLoK;ISltA+#cxW;iBtPpfi|$pLdaY6jFAg|lj#fXiKc#qbq*24dnvr5pUR5v zV$WYvX?=ukl<*=H6Y^D3b!VR!q8CCqlL>l0l4pdYYf% z@8Iu$zED%IIN;w4qKC(07Gc4D$xvnpqszZ4St}u4y!Zz{(XZxRulhC@+e1LLRITV+ zH^0xd%mE^9n)@Mh;X@Jeqa9vA1X(tLONT~Zk;eMfNqRf7ZWFRdbJK61?O zcVr}Hp4|AgVEY7i%D`}Ov6!`{;qQL&FFQ*C>rZ;sBWxsgU_4j@{cIs2D|L4uiXD@T}l?PShn-m(_ zHNevn;C*1KbMgLj@fEsfJwsB^u6B_rA9M$=+Mb^nFwt(z+D_kROS zUP2hz2O!(Ah7AMvPICNlQENX*5`PEJLdovxnMKLNg;sxt_MQ;T$)uN_X}wFj-Uf&p zfg7-l%#djJ>337{Tr!%$g61Ee;|kS5nVzZHFNc;v*K>uPt^nqioIFKf`C}ka_h&K@ zc5AdVYUH(fZl`%_^3A7QDUVp$%PPzXc!=-A1#WO#k@YC@zWMT?fbZv*m#?dN7+44F z(^F$+1?Z~d$3;YcNn}s-a4 z#@X~6ehUqAA1kkHWY>RDpEyj_!C_ESu|8gL$T5lNltY_amOo;OR?Q z5aB)ohZo@W_D}~nJySoyasusn<3(9Bh-thKt>_)$n@qK=HXR>q>;hW>Ya>Qd6!`4E zX$?T{E|dmbPy5+9n27gI92<6bVi5y=`1d2HrwxX#sG2G>G+S?8);Z0Ov&Nq%F8<4Y zey!~s``+`ydObQJtJXyOsaYeW?Pc&~b2))gUDfbs;+i;y&XiDv82uR-#Il!*FhYiY z(CVo{0)quU$e-3or%)=Y4`zk);HN_W$P!3FWRu>rTSO35Rz3feHyQ^Di^?O^?Kjgh z$Oik|s@-+AcWO!=#SgQzs$}%_=6wA4l512E&(I+GbAoKLfi9Qb?RRMjKNEDuiI#&B zidsgiZVs+cFiqA8i-1tPHF}l=r~r1o)8m|T5k%qbPPBPn>s{)c+E$enL9h5~sNwMdNeQSxh0Zn1@>!WWnD* zG*s9u<-E1fvGT9uT)uYstJSjkKh@P}|7Qjd|IVM2LrZm#1Witwhw`DiCUf^NtSxp5 zDRvKTL7A0q$3JM2O7KpW4`?Od;W2;`-^UkKR{jtP5dfr)Y>!9GAmy$s#lg*O1XWJZ zetcH6MNA8UOypR;A=P3lO6KS06*k4fxix4Bq@^ri@IE(qE$*$4n!1Mm>bV;J9~@={ zQW9g66BCoc4D@(HRHG&AXK(Vb3U{|8FinRsP0So&aCbe!W0$?XwTm?~XkuDT9HZ^* zis&DlslU)oRn8R2ZP;y`QOV27x|H0*tYgUbqRGV95*8Q!uy1)C56hW(F3D(RqHH%k(QPK(XjyyRq2D{K z1xj~Rl3{lGM6L>N=_`YT6}Z@a*w<3W$A@rtb8vXKUDP>U83*(Q>eO^RHr%u)j$n{d ze8fsjE7O?+gZfFAs^s_5=5MolQFjF2S1mlE;EEA-QogP&)o z$~j4`Sfx&4;O)VyWcVrRA7x0VVFY2eZ)fQg{xj={DMP*Rh6I^GdY22yt48UigS(gJ z0!0AaJR0x_*~Byj_F+wVF!P&Wzbvh^*-DGF%?Mfpxfs{q>?|G4Ua2{|`%fO-K{s{X z{m5+tA~ayi;Jf)gv1KnV@p6v=d%7;E8HT3cF^L3rERG*^C;p5majFDkO)D+BMiCO2 zaXqu#pAVU`UUE&r%)VVxCzu>Yh{GU!zP{)T5 ztZmE?ebqB%y*ln-L+Y3Q!=}hH!shzens}`!T!%J?#YFoyfw=`fv8$mN{E*-S7yd&s z)kdwY4ORs|9e!sCFF!6BQQN79h3Pt)x%{(d!W*#qK2tevg;v{zrcwakL3L#tpVqd?~eUqm`boX-u;N-l1#p=R?jSaQ5( zNfNtmf;*M%QC%s)y`0-9>&#FaL65aT*LKVVYo-TExD|I>$Fg>8lQrx_%qi1Vucq|5 z!R|;SzCcE~G^p}*?30JJJrB9!#Yh65N$20qn)ODTuU>_X0T&uqwFJCP_ugOuHRWZe z$DV`3a!dnWJFcS*nxZKwHf=q@B2U!%W*@cTrau&68Ym1Adp!2Po)gd!@bLw;EB`Er z>V+KcCe%_Wf$g>}$f&?m&RXUZ7jmjog2na+!&=pQ>9iYqEv65;f}IXQquP z*6$>){#^9cptfvUhl-GO?c2|gLAHfi9UX^4FL}Yq*ZSPN2K_~kbjs!{Oev66>NXK+ z-?o}|K>*EQW*U69%C9>M?#SUpI-*=rq}&izM;c%zY0&Jr7X$RTlO~ONvQR>H$Y+hkVWIHiRGZ~$xwK_qh9$!g*PVeF$FM~0V&?P&p@eP^*KDe z%C3P2U#+1o+oayXj~&8j<7!}TqoMQt4cx#RRjIw$lB|$qwXR=2#%*C*{t(%PH(Tlb&5v9(HcA2RcXLF62dd|Ov0603{^^ zk0n>j`cEf3K}VWo6a;rn1C!XbbATbtaF9N_gFOwCT)?b1J5o{{?Kbc2HciG8I$jhd zo;w~(1ngnZpH~$GmA8QZ7F9gF0Mz7LPYY5#Tm>McUg;0fy_Q%uGrz9*TK=|~q)PHq zmCZ~tiIRz*xn?Hn2oy?2rdf9MF(qF`w@9gB?Rf_>q@Z3QV0AUoOf`W?EyY+aUmZkU znE|Lq*7Am`?)Kt5H*jMzu+7k!ExaDC6%?Cm`w^;*op7@1zg-HfUUQoVw?^3qqczWU_DdSCRQKzo zc`J3$%J3EDoGE%tv@wg;29exqHw-Bk12B%{{8>H_*ohaPfC{hugj&Fzi5uMI1&u>G zt`>b3DZk`<0?g?OL59^rl02}Hz|@SEXZY5lN9qU*X+z3u{zFv$mC!$l5N_4^xlgiq zx!b~L5Nv68`iE&MDI8kP_J*7H(S=aFa zSM*}1`pErg%h^alp%2`am%M&k*;-5TpA?dq2AYHOB|iQuh(E4NT+F{t+Ti``~lv5d?`?~PyPJ(1#NGe$G@v)d*kXe*Fn$NKa< zM6~}7`by(-*#IUKb~zKPU-2^7-oQZCzx%~qDn9R>DYLZmhnxdl%Lm}b02_u>-E25yve6lfiC0TsBnyR_E{>by8>IFt;$I|!O&%|SE zCm73WoTr{wg~Eki;v0oWR@GQ=D{I$!RuVvDq;g;-IMu}FBg$5Ma8hnIW!VTA(k>>H zmR9-)eP{Qqp7lB(sdR}$eg%%gvpSP;2?F`PcOkifl7;2>*~$P$~v& zixSw&BX|M0D7FJ|DWnZ$SStc9<$0+tP1|Zden-D=zWL?{(C7uf^-16Fa$p^v2s$jd zSbqoPx`t&up9Qykbk*Kc&;_+AhQbewd46WFe>a)!4k8SaB~R}TAXC*Q^O0%WbR?B9 zz)ijI(4ay*CWnFv*(jN}Ufq~EkNt)bT=c9)yMt=N*J(T5o;pJNTD4Gl|FvmbS>mYU zJ2|T>E5-pswE+_b0Br)B*|-~i=?Q?jP$1tik*7id0X5cy&}kl9{s@l^~7x!MD; z+g2}K^!1G~aRJQ-ZU>w#r$4T0T5kV`pE+E8HKVpkuw%H-I-q%jaTY~90zi~^r5+=* z^$3ZafS*f}j=a9|3rXDR!3UCIrtX_xV_n%!hsuc>E1@j~4ZZ`Y&+p3H8nFS@=k1r7 z3wZ6GQ|x%FX2F)T9tcsp)1;lu$J)2&>Dx_y^*^{XqObj$t&7s?{*&A9Zw?a2YC5bt zm?<(7srOguGsvYF>`>i*j%%2fM_(WhH(&ldtmx=%>}JyC#H_>|5ohg%oWdf|qF>!D z7-c|Bp*VhYtjjIVwquJblGX5m^1*@PuSQ=Qa(qW3W3QLDJYUti0Rm)!$}lIj2n?oC zM3=-DsKkRkFs^kj#eR-3SK=VvgDp7NR5ne6-==^i(!AGr@mYyep^QvD^_7qqve2Hy z*!MfAUA|p_0=I=Z_igs^ycwoa{mMW6#bwtcy5&3-MI~BxcEVp6A*yq#p#wA`(bjn7elZZfF`F4oRmo}##8>TNBk%8vbz^@T)-8< zt*PM&$5AJn%%scD%ksdfvhl6%Jo2fP|kaA7?jR)9av)@&|}L4F*QQsf{i*lnv^?>cG95P8wrxud;o?2fe!%eKel&$ zgg~bJ0Mx!EW;5PDTh9!L^~-v^QEmikp6L*llk@oYCUIL{yL|#2wO@S|%q2;XyYH!% z0LKhnR{es%Bj&uQHa~9MuH713QN7nqeAGVDuUcQpD_8H ze(`IslaaujPPsEY{*#fx3;x0x>0AM3NlqU8+a)yu&Tm29EbHwGvkgJ{Y|rqF+egcY zZACE~%7EFlXn_SEIePL)VQ$)8OtU0r=WWEh(rWml;@5DdIBB+i3u}GRmU8)>DO#~5Yp}sEPSXjW%-f`p++Rm&{|Rjt)S&T6jJHB) z=v=tER^7Bwz+fblec(?zYaD}A^USwF0{G{y!ICK+r)2fH&j0F12D5N9ZG6TGAC-u( zJSB2&zO2H|&koc%r%J9(Ro=Xd3-Y!~&z?+G1kY!6MMxy`23(-BFm@&Fr;q|JjVvCh z#mC`JDM(K2i(C#MD&&#+AzLG3OinPn_OgQcu5MQcenecoRT4o}2eVQq3qxgS?mrfx z@KAj+x}R6O34i;CU8Wg@B*&ykhvBC3ZRP z7RY_9lr(opU_n6a3V%5XXN~cH7j9xu26bfkVa2V)Rz~O@%jZWz7|BdaoY+^v9rM}U zT!DkZrpNMzE)*10%&PUK%7+`>yZ+jtT4=pP(R<2zf+jv}9H z@Nwb@-qheGGS^hBdBSQ#2%8ys%|RqeFrK47MM{@NMde}K<1pjL@V5b-*|@Ic_3qyECQYFE{myx>el$_pHh?YD6`b06ni3Pp!`eqiej_E6lCK^a&*XIh6$=N{efxIt3K-Z#mQ|k_lF7?SxNnXSQz(|c|0K@ z#7|bg4Y>IaD=QpDU0RqgSoL8lVh;M=E-jF}lEIu6JvdXSv2%;Fc?~IDl=Mzm&tI)bXvkFVH<8ivwcUTfFsfg+(wX_-Z<@DRK1(^!$-uO=7ex!kX4UkIHNzv=1 zKQ2q~E%_OBm(iy19tA$TPP6ob2ycQy(IFZ;sT@o0VcAfa!P8WA=pVR=%00PhJJ(1a zfzC3dc7mYE#r0(Pa<;NstB|0iqy&Q{zx)1M!mL6LEgicGd`a^%X24M$fTq3(e2Co# zx*|79En*u@dX5-;h}<8zyioH`6>a0vbm&Kehq2~7gHEE9&OfM$@Tt@~31YrDe(pdJ zJROHaQ|fcGVMT29@iI~iRWCbl5IP?$-@fJ`eW5*^*?GV+--IURcNqNjwWF%4T1ioH zEkxXPq9i)_bm^kC<)vvAB^;`$20$9CMoUY?Z&zYKYKKB8nat%{Znq~9MUW!5e6z~Z zAX$X>1*rip9uDOutEvO?LB(#jM{pPy;9ieZs>{Uk1IKuvBhd&B7Edim3%M$PAQ$Cudi&j*JC7;A zsJNc;2NjDH)s1ZIhLXdtUwvP8vfhVA{#e=EAn%N!PxD zoo;T{A1FU>>u5ibv_y~&euO)}dN5V?<{4MP5B2x=AcXh6+UFDvnLLM&HS5Zkz16M_ zPl*t?|KhYwQ!_@lr~zIu^PJs2K8}xFgYXse{l{aBnh)w(KTi4O^#{m%o2| zx#WpL|5|T6SO9l(Tj#U2z?y|_ckGvQQhot9KEuW2o`!}Cr!clj{vw@7a_1V|(ZHq8 zpibE-wuf~2cdB3;&CXuPVQjn4GN9{`WP6iUoXZLY%dXGB=+uSZsK~cL&-}P}+xyX#8?RsjNkfhhvbgm`|r?Ibj zc0>gx*KFLdRM)x0$Wc!qr>00_AfkD4fw+A}JSm{O(a^P2r8H8)q1DF(TYfx0FW~Pe zIJWlW_3+FXaYXj8VXXj~o5mQJ!PW>kXzy8yh|~bO^zVzsLalt4wzIXN=e!lRz(Xvx6kF3z^I**4@#|GoGw4GK|9G11uZyvl}C6AoEp6My#% ze@BFBvvTPW3EI&ktk0{`l=3*;K}S^Y=Sj+XAq^E$&AF(^&uwgdxTxra+_GlNnbNpL zz0?H38+QYz;mV~QW8IG0rkNMJI^qo4d`A=bdn>bTO9#P$_6JnX%yrvfz~+<)24vBY zGbJw7BGPwX9t#NIw;zEIH zmZPPsBT3l#`)#!}Gr+&nZms1m>MjtVp;9g#CoRr?SDDgd7c|OX`EmH%-DBtQL{yp# z=k@m9!V& zLVa}eVukN%L|BkG!qQYHtSV3&dRKLbhV&g9uP^+ z@9$g|V6Za{1eg05*IGl&Po}H+#b7MLIpeA$L^2wCg}Jm6Fa(nM1{?q2`>0pbawdO&oFwS$l(Yb zTszEZ(x&^W#(Oq(!4tcOS+We-zncgwvV;+~W`3rxBI0L8b8tM5Y-D9yi)c~p5QdY#R$$z-!@{S%yMTQ3yZKPIz+!jP2vFTb|)C7u{!D8qN4Mzqip~3;6UOD)kwd_wDl9ddD3QN z;Kw#o4u={E)kyN}(&BTzA-Ri0!OB_*>D3*V$IWc#Kr1wxva|+h%eop4CG3q%sW@)NG29i@kyK z4PK2@w|B0o6KYbobjTL)$r|LBMY2WXo;x(IE(O_Uck7qU?7mRpSM$j9Uu46Oiw1eE zN+q2*Os|uVjyWC|HIBFNb~{vx2vG_Yg4>=Capke&!fdK+X{N#Hc+rG&e)(ijBc){x zyNh(=2Mxq*5g=hOOk5zzhSsL^$9oHhf{8sTytM8qx(= zormX>wRK47Eu7acXYt~7$5GKmYfbK>mXSrn-D2qB?0l-VaeqJGF+;~AZA%xuI#hI1 zU}3l2sOQ>TWBt{k95MDZ5k(#1elWH?8sRGJGs%ib6CU;Umf8j)Mjj_g?e0GXCV>tv zh_d$%TeBZqioSV(#><;x=PS=K#-1o{0g8 zazh=8R8j3b^3ra7_C$|8f1pQfvjzQ;>eAY}>xWtTzL2!et-`Nj*_gpO#CfsV?uW{l ztg*kKyR0*G45}pEwys@psL{|Vb;$p}+WXG1CYvC@_*p;{0Rd4F5cv=ZO)1h0NSDw< z?+DU+uOX-uX`(_vdJVluhtL$I_ufH3daoe_!o7j-?tb1q_wSy^U$EJIXLo02XJ%(- zXQd5$*6Ixm*OGuJ|KD*Hb^CckF7u>_1(Sw@eTLK7fF8KpS)Sn*e*$`C$bIT?v9e*^ z)*ixV>+LbZyXYC`eK2gjsUA-mBom(Ksh>CGehTcqehZIzT`$WOf*-EaiSCT}Zr34B zkA|jkRQ2<<!7yQ!G;J;X9Fj8RSQ4 zvzF@Q6z=P3-&xT7^?1=@A=e;XnxTBOu6AP=gVs!0z8pTzq*I#e%;jCW_>Z;>07?ke9@60Pg{On?wW4&L~)p=Mc- zYj>KrwalMjP&ksMGhwN^A#ZDC8|JCcU$@F->-_-)a(HKZI#@)RS02-_r_b**Cki?2 zi-4b|p4Iy7w$YLeZ#3~I0ug53h(&l2b|tw@)Bs2&Wn3OJ?bdSV44akgV-tFIe1qSs zNaW+8`%+z9Mbbp<0DppTrStLrU_Fkvk8BeEe#HC}(9_&k6;H8o-XS$}1E&fDr^DD7 z9iAA#A;cA?jJ?sD>0clMBt1C&X*dc5g*-?FDt=J_0{{Q~Z^B{!#OCNB;i7eY@I7i^ z&;C&v*n-Uw|NZwb9{w`H-^K7(68x2jf7QWXwfNU2_-h;eH4Oh+#ec2hzgF>ItN5=~ z{C{s1k0IjR{%0(}Umf~ahyK-}e|6|z9r{;?{%;+MxA%6ZXKB%%@jUU&MdwCTn`iWe z*~vwRo9Z4l2afuYUb=am@r|s2f#B#B@h|#B@A+#OYvgW^>RlOKa7gfw@cTyIX(|5n z>k(*Tw7HT)SNw~sp|c@e-F>JOh*KUKP=_nJYAWr$OHzt^x@EdG!>72MPnOs!mZd&L|lvuxN_A0lC=nWs=aw>IJbTcqrRCDT=RTRpx ze68y{f_~TbmXAqnguoE~abbrRbxb;2ABIa6@9*46lv?QTKCv|4jN);Jnl9Uby6Fb7wV8+ElJQD~PORpORS@UNSYgHoHC^Upm*0^9&6LFl%IZl!^G%c| zeSX~Hg6-%Q+{@afBuW??LTa54(~n%-B3KOW5j5POeZM%xdMCx{p84VjNJWpV!c~1a z;qw61Z)jPCt(laF^+9yddrlN*cjH(1s;Bp&hj|gLG(ow1w?fJ6r`mr0e8aR%co}v- zv*ZR=wPvG@CLoav9Uc7;I0*w89rT5_j?*2tb`NvR4$*^SDwH6}3^Oe2dcEaGVT4)v z4M|!Z|Bh}Al+!Tgf--|^K8fO^Ag)!B*WOd80T90FSU`S$R?q~HDn`?PThWOdvH#56 zmwj3MM2s+smrIdmFG_Y`aEo|y?qwYv=vXAzVgw{7-=!DH9z(C>qL@qrfcc%a&o>cn zJ7Ni06M~?K88f2q4iZ(82{tTT|kv}T?`Te3FN41@zrl@zt`pp&A85B3r8QqNGUyC>HTe@*vi*k5#F?aDz8z=>gr^2A1iRhog?0JiwOD1bW z;#RY5;7%0+uYE;kP%%EDb(0EozoMhm(r;WR{=^(#rp2wv{0$2Raw`I2zD#X}2<{MC z?5pWFBP^?nyb(YfJQ2`Rn|Fm9^!#@aIb8i?oyk=c-Rjo5O zvuG?6Q()LXIQ`!!UR6Doc*Rk&(+^@;C`PxnHp>O*b>7%8{Py*ngL}2cQ`5+7htPrl zu$c`Fpab_)3z}kV=})B2=WsVlNr3|W+NSE?Y%66Wn<~j==^ayHmb`P>LSD6-1I(~> z+mm~oPV$+6oOBJ-&n0AK1@nLPByu&Xk3N4+6jOf(1OA9dP#IR(ZquAI;14I#n`nfMOqyv#SH22@6zPE3> z9pFhj6|Ym@+Ze|2M^}`+2Hib}E4FiYpV|LI7`HI9%OnkI=<)?O6Z>O;DCfI?6r9i_ zvFb+$mH#pd2*!m&W;^4W+fB05IExq9Uk`aZ>X%E<2Xp6W2BME@vr4$=^YsPL+6&;QbDO>#xfPX1v zZf~#oE1ez{r82M_(jx!U0eD#4Ts1b|b^>`g!h0`Nx@PVfQ`*w58#l5|OS>h!K619KW;G@i4sV_JFwoD`Q4O3(L7$aH)RvyGQ7 zLLa@`h#$eYFz;edR@zpwF!UbAnEISCK@5H>_^5kBmlH^3sE}?w-)A8d5AkwZFP;+h z_B~5|BQ!sa$Zo)tBra_TA#mta{HuStljS!=olg494Fo*aGmssX_%-WjyTQ+jab!;~ z2m?c12b=3ih{#9{{J}2SoCIjro%AOPd!g^hZaw*rF0=*UdY2DO_e(_rKTH*9JyMj!P>4B}u zdefiVaa)tP-Wx=>gkNuH3VP4hHh#D*&RG;A6~TgzM*xv~pl>e#&Yx~zTn2;h(?9T- zD%aF^Zz?SOHO6QKYp+k*d^^2a+!jlj#R6@y*ch$dp|SU9V&)pNlk9f8F6jdAdTBVw z`!VT3a)RK*_4KuIYMR8e#WjT8S|9~$&-9>-f{DjB(U=|vLC5h@%Evd?s|UIpkBs|Z zRT9DZy#_4j>AO?9qFpFjUuAo%RoL9EHkyd`U|*dsb3JVZ@Q%J+Y#dr>Dcmzv;*7ha zz}C<;%xAlFxT`R=Lm7>FR_0t~;y_3DZ&E@<| zccpoDBnUfPguL7AoUViIeaY0@!g64nt_x8UlIGFb9!9Qw9qjw<&k3JFX z$=+M#X8l1kqkr~C2VD%6V!TzSE3(X%7QdLY449V;9}RZ;a4(GIa94hM5TDQ%C7+qB z|4Ol|8^}29sp$h`bhB|9pQ4xM_^LEBoN9=km#oNFWC=eToUy(iIw1EzhE5oQKP94v@5e$+@0l^ib}#HnT&{yd z^qXcnbgL()-?wZY@1)mY7|J$E#iUsIYCfq!3uy1JuRy72@Nr6+Nu#HwH4I)S+rg@@ z^%J#5Rf7@+qsU9%%yOv=zb#1!XwbQ<*2)5mhpw$+!}JPLs%gUh-dgxgTm8j89T`?W zo=OKVCn02a2G1Dw&FbKAluSGSSnM{YjrOyyryH*Ce|5IF5f4Vgmxwvzn7U zd}qiQyw+puh$bOCvH5%=5Mc;^a{C+AmCnKSlOHB548F%$#97-sE+V0o3x}H&!Uof* zdo@!_``iFK8FjUC%k963%e0Iu5CGEnfZhQ)3rvT24CFk!R8-6>*y{&z&m|3abwt;! zFR_{q@}emn2cAA?kwx+3$X7rCZNov&S99A@V#FEi!<{H=UeGUQX!;19^g)Vp=WC{= z2503bsChvGiLH4Ex%h|mq?(Pf`GOl@yiz7h8qi&eFF58F+J8I>7MqW38x~G%c1(C9 zqAKO+skIO*IkmUe8Q&vTGU?$8<1D=U6Usi zfu&S)(Kn~&0-&<1SlZ5&)UE4nB$A69=v6J`E3Zo^r!o;P=yj=n{N^mqZ?zS?4g6J4 zaGDQY;A~d+cof2g0;-LW+Ut&v+|ECS-%2C(N;JBT>_xJvlBQc70Kk4j%^2aAQp(zv z;|^_cH^G^fUtqvD8XSnN%NqgL86pCoTl{3Uew_W3z}p}Zr!SFWF@DWuvtRfgsJ$XQ ztYlFk)8sAk9;(QZb+^oLL2hv(3fcUQ)&m#E_*+6$ms6(N|4!^t+c;kOIfUd2A4T&`ECVT4^C6kC7H zCT4oovZpDR4nPkJVTvhX4cbzsi%8_|j-LgEDN4<(o|FZsp4;)DT?OjDgUx#$kfN^) z4p(%jF=h7>g8M*9zLQTlV|zX&zo=TjoVK7BlcVmuns=2tGm`-E_E}a=X9TP8($=$C zF4LuTZ1G`2p0V<4E5aah_XP6YlC;?MRD-Ww3@=)YMEkXx@^AJ?hc!Nc7tilzg4Cuj5S;Ztc2Sn6X-cs3-WqLP79JmVudU<-k z!8=Obkc3fk^N+K_$oo4v4k}iLU0^7}V^Z|hxhmvU8gV^i$mVudGo?9!JdTzyrCE

-Gx!9IgYi$ZzX`mn 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 AC;$Ke literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/build/replace_component.png b/docs/docs/assets/images/build/replace_component.png new file mode 100644 index 0000000000000000000000000000000000000000..bdf0cf68522b6a0f301a97ad1cb3f500a4537587 GIT binary patch literal 153690 zcmdSBWmH_t7C#8VLa-n~f+c83aBnmO3&8>;Aq01)aceXl2CNaNnP zyEo2s-o5X=`)0n(rimxzA2Iw}?H`taksxlZD<*@|U#yIGEe8<;1E*KcZ@IM!3 z7x23o2F6{UlAO#tPlFw#hmY=r@7>)5PD>-oAe+VJEqpY|+^a`m&fP@3zA6!TWq)Z4 z&Ska+j|p0*3F^;RSucs6zNTZJ`_N#bTft(xFDWXgNr9SU3Ann#!ob%Hpy1G`;An)# z;@K@iTqbJQ83Is2E-~?m`d0U%Zo3Qz?~(qqTs)+i(h0Hn_>r2F)L68w&1rIXa;FNv z{cIprM(&>_KZOrCX9DB(pcHrz=_E%@SnEymn4zWJzW)W&KMN!O4425P+6TXTHx>j) ztbRgb6h{sFKWiM3nr}b0s^BL7Cmr#z&%kbh;r}c?t{g4@^C5rqv;T7+P{&H0rC94f zW70whwr<|5o=Ib(`fY&~Mo$P&`v-TNFEmJ`;+5rE8^3hzo_#I-FGIS&y~OV0 zc&;5u!qZ|I6GJ#X`c~ak*4HQvm-x{?S&Q%7gXNRYQ)Wr+>h7+o>qL>$ObYU6{`E+4 zb7$v7CD;6X^?&M<)_ld3GAtY5CB((U1!%cNHmyD2C#P$dS0tmQSF-pVguWkmmto>) z^bpQ_Z~TA0tsU0C#+ZK{CW$p-uW6{Os@$(JY@)}~r6?e{({7(uqnemy%-(Z2l-p5b zRS09(v{mHEpNU3-yDVVwsdTE7Zv})_!>oa}$9C_I zk0bs&9pT-NetVvjcja?yTBI$|tHDZ3W5+`uxAjXUkefKw&DQ8~@3_;Zuw@{9U5Qdz z^7EFQYw=^lTO43R(}OQ7k*X$og4DwMV(#eS*k?!*(hTLAt&!8y(^sm;$5ymH-6l)5 zAzd72{fBHMLko9XEvakL)wXP&Z;FCGM~Mct*I40(r5mLM19nc%h~G|3!yV-~b#S~` zSlSoeYaPWiSlBufwI#5ag;Qbnz9(mAq-#X?iHQM9QD4}Y2QnM?MBRkGpP5Gg)^kNA)=W~og{2@YdeKhae=!9{@LciN?X3r2Z3yCC;R+_0)(eEQtO0-8M#z92tEK}+3w8ag_rK4bW%yTFcXd=j-Rx-rWaBt!2EEhP#6Ipy)a z;~{wGD!fQGJa=H%29QaFifP9Bf8^B zJ7GF^D{K38IeGS=Do*c=LOQWI6&I}+#Pxyw4wjx)Dc`#tk0OsEdb_h~5%S84BJQ-J z8ER@!d*jJXChp-->$J=vG5LS6dxhVU=f#VwB)3Jg)RYqsVYJ)@jcn%r$^pknu`eDf zq>Fc=2@VS*rKAk)CsnuY;-%l+l?zU7Zsi&vjpk6UDMkr)^EvQP~9N;MHn*NnmGP-)U} z*&Spc3|G~AMP}hixoWAG&IvTiY>qt$=hfq;a!5`*>3f%*nD9sJo(lhl&F+pLr2j*- znVjWQ(lDUO#sR&%xP&{Qfg_tI#9(VptcG4cZDuZ+HiBee0^Q)Y}-c72ENPr zX}|7reSNq-IcB3uno2x9c{+=JU7Jy38UIy^`Nhk?2)Pgp>$-*NaC) zs6KiAJhELh@!-IbFtfUvq~0a`;D8q`%X7EJO9=ve68cy98Ijct>v_?jsp^TlUr=U6 zb;r8G*s^m$vYg%ICvj5>9djeDtQ4BU0#j+!ZDz;*uBQ|9i=ND8eO#>U(`jNtuUtQ7 zi0z7dT~q_hu38L;V;as}in7zVLAX;K8d_BSclYaSTn=hC?M3^}JcP@B-{NwU1?pAnb3 zH(}<3#Xh$b(k~>sY*}GtO-gD(AzvFYZZ{J7voSKKKpej}4L(~GYt!Rj^U8N_U)nSH zH!jto4o!O)^kWy1qifg-H zoAh%{uY>5tgW}ZuKBImIKh(8WgGao$u3}$Jyt?$|ebhJAeMTQWpFk*zW{6u1v9nsd zZeXGgn@PKPkl6PgCEdmhZHlKM9T&uG8EbpJ}u2N6D}2$npvMQ7rXap$DPEX>d_Tq|3^mtKI1<{L`%OLP^7YFa|L z_{#b!=eJ?E?HZ>QH$0U8+Of~=qVC5O%1$HX2Ls>rC2Z@JBhu97gkKZI#|`61_zm=0 z^h<(qnZ*l`q?V3a;avWMG_lZ{9aDt<)l@?>z3$qBy}Lg4+N<#)&}kBgVQB=#Z7!HQ zq_De5c^O)Af_JLL&dp5>yQNmFFX9NSi>1q%i(=s)PCL>NXdis|@R9PY{I1*9(9ByI z*{+9bwx4}o-;>^#K8rvc_qYj!yH~pyZ5w+RPsv}qGETPNy3?ka_KE_wtboCG%K@O?B(iA&XvZltZ(dXuk ziid!bZJQfi$~#udclKgo&qs{DyT6#Rr4Wo$Dq}4(vc``mbgIgqOM6Z}Hu{P-PRJ4y zKl#ZMW=d;omXXdwc=R}hbTpmRTxh&dP#dppTDPLE+2R=IZ){j?=$4E7`)@CFv|MQ8 z`qOdnlQ)zb{!WutOS~aDC9+-Uo}d>F|i?j!bOUwg}X`xuqMPtV3A{dxCyl zq;0SB{XLcC+?#VeyJR{_odV7~NDf*w z5wjom=02U-T?Z`B@t4WxX*QgAuemk#yudSFY$U1R>;NWeSvhvsnLYTmzp^?({A$y8 zmRwN606+_weyzXf=5raEicupL16vNd8LdL`?$lzitQ4TU7QPP;$)MkX&G+?nD?s7sU7RJUmug&{kodXVk9DoUeRiUuHD*u zzoVg}NWU?l@-5io)OoFi(w(lbz-2HZB9NIWuvSE} z&zAR(=LT%VBp5%muX8R=yJ_s)8E*5b@{C_D04wLbq{9@pn*Fa9AMx+bLIbn*gYJ{9 z&Gp^9;Qw5Dm_)QwXp@JqHX%^YHR@2+(>5XE44Jmr0DVDQn?Pjy?X()MFO;AsPtQZ0 zhK9H9Zm)$uZATJ+4rGl`5N5Q`L|A|3N*e{d&=L6=GT&&zRlf<>3LDlrEUbSa#D}>n_7~N7}{XUI^}DRKXCRj z6~Q9=OPiGQ{CNV#kqzf<^>nr*?Dej!w&R?}YBr+!{amfbpK5g{f8BD$oaAZLT|WM8 z!D_r;y1oG3o*J>~-|4>_R<;91n+_b=euSAZY?A7yPhH_Q-}vU4Um@x4kfokZ$^iN* z!Z+Fm@U(9PJ+W@Xo+tVSo=)ssNrw#VJ~7OffXh8FogG~ZHiEY_px#S_M;b+mN1NVG z$z$A~_U)@hP2tqh1KOWq#k93PCuf5satfffnzsY_+SPBz$koOhz7^^HO1Pjgc6|?A z>R0_194T8zTYYp@{Qjgy5|t@#fouM=#MroMeaL>P&-P>O*5eN)&rh-UL!W!yt!htc zZ8MeE^uc0hKZeeHdWDTs5ZFMo0?4#p_m=v;YhL76xk*rhrh^O-G}Nv4dt48mCNxoI z7h1Z5S2%xp57GE585ZP3@l9XAo9Dys!q|M1s=WV#@TPQs=lpeA_1QQdwRZb^TXYk@ zaVXeoH)(-&wYSc5UT!Z=;rN{CF|CalqV0h8`Wc=G@S9hnAkCGNAc577bgA8;- zpU08cd&Q0EZmfL0x_bi4>4J1ViKq3lh$PXshs343HmvUB&f`UTuN|TiV}7VM)D>Fv zi8*pZ#55Hg%#7$cR8hIryE+J6(6%FM|C!!4t3ZTHsDnSU|H|uBo2M+V0ZX^8z*i4u zM!XphKOwqTF7UBx?eTACNtCs7gr%YF_}3*Q(#v_IY}doCWUG@XWlq>#VlOG9=$~Kl?B}*Lg-9Gzi~c$(}uL9r*;j9^e|Wq3Vmk5tq+e3@oEF zU|&btlieFg^xr3vGd65n*A>^W*uv+cf#kdWX`!htJ=QgdHSa>0l$7u1l z?MIEYn0jX{9)}_eG5@7?%Jt>Uh>Y!O$9&W*YHp=j7ROlxt*?`--VV|377DzeN?;Uk z+2rCmIvPkCa)y51{&&13(eyu_TE3FUjE)Ht+!4$xC=oTnAmgecn8K!3kXYh}-V8KS z@!`$1PdJOdz)l4hb=(#%*l$olFlxdvV4vnv*jU z^5pagV=x5Et4e!k)m8gmh{xR)u=__iV+pU>-*9ng8`^Lh#;=lUsEb9q~XN-<=9$6$;WIiKR^sGTqP1?WPkyO?8 z5Wr&fIF4{T?p9M}{prXJV@5dFRDC0^_?W`Dj;!bLC-?2}I9e$F(ygq{D)b_D%Egj= z&M`QxP9YsY(0wdbwljAp2F%!DHC{wYxE{Z99??=#MHqL^YFbeLqWk$H+u~UmPSYbc zrx@lgQ}?0W=Syjzy@kv7%BfIt99O4RJ(LNv7eSG7ZxY?oU^)tA35Q73=t;$1D>TT@&Kr+(l$tW8=i9bY?}SsfoWY z+F6+YRC5j4mylY>QqWFHOqg*QU@s(TR(vTa!qs=SljF$kVrfoBzxETTg)rW2<$F)p zvyw~Xn7>45`8(Ee$5n*XdWuDH1}l^#CR~|S$Sq~Mv0yXux!I~4nsKVE9MdkHduja* z6^#s_IX4NUdn@76QkqY_XY=mUb~#h43% zVgRCUoB%}Jq)R$SDe$N0rpbOqOLb{ON8v4XB(UMjPZ#bF6P;g*n$aw#eQL^`cdWG` z?U#^7nK+B%HD}Oe5Dl92%nUh~pMbHzCPs+mJbO*dbcjO+n zJH|F(ao!s#=2;kPFZR(YK{#Mfa!I~35;!%Y<|F}K)65V7hUTCJ$To?0ldg=-lIyVU65hb%!@f@%B6=8x^en< zcq_ipRin<8nmQ$g8h4W3Jv20wnwq+WcZXUSeCO)Z>QgQaJV5Z$5fT#e3JL}@_wC^m zr?KJQ9$)I$T5#&iI;bp|NAm>aH0iYjLLmFqF_7U^<%A z@QroTeuHJ1r#ZtAX2(N$Z*NZCcE`8zXS{KBp|tCH4~2Uu;ZzN%a`~=c>IygS@IIY> zUy}Kb$ZYg>u2#OfT5vIDE6zR|)Mgr&81|fozv81ivMS%aR@elZivmEDsT=_=qGpJ(zPt&|9YdcpPKy=A&r_6v8E2c z54^C`aY-R1IB~@}t4m*Ld~{O#P~Z>|5`j!y_L(Rvs95>Y5N9Y|5c|ye!#o1+QJneA zJ-kXw*YhIP@NjzIleg@3oYnAr)-@qSLT>df-Ek7)Dcb^`pa$Aj2?+YIwS7+-i)ZCB z@-LUNdqw4BYBo0|MRdm<9sDCA>QAwt_S#%LaUJCo6%Fp+YvH{Pn>isEO@*{%_U{=v zI)=~1h&d0#X&ws#K>4J}y&*`4t`ou|K;4`q(Y$;dZNzC64~4!4JkZ4M+suBvreA7!(s#d&|U}EMcqutiE4Mr%vp1*lXo}mXS2Z zCod8OGYdxQ71Sl8eHXfa)0=wM5b_TbQd{M77)caFWGsi*=sn;>T!6M|H{miL9KP!q z*|m2VFv!F~;5s`aCuJHJ) z@vVAxQi^m2CJRJC_hRl=cf?SZe|?N&*|^fl&ILuVP1rS{zOZz%YusaQ(F1XpU?_DO z>><_QKK(hAF@{x$>-?2`a2TeftNSOd{2163=eMh>qdoC$ufxj5C0q>B)UtbP;X{0b00zj355qoi4@cpYxl_mChd-jW?Dk~ z53tWa|G2~6D-O>Ftc1vp3{ZJ)-pG!6sOKV2L|Q@4W#6i#c!&9A{U*v-S)E&RGX1dS z@_80Q@uU&5)nDUj#pOm?t3CHRb_H=BZL>7XURc{$b>@PDc)YfM-fizbNcThShZq|E zC)(O0nI(>A*nm!UiHU(Wc6Qh~_@WycBpwh{q)H2cjcB)5;q(XsyAN? zi^q-+E=I8ml?JnFuj1Z(nog=p2kq(0YS>A;;fWj^jokGD=Vp~N+?seWz#=Ik8pexg zPe7K2&g6dhW6RH3?bzx(74eJ#>PvKrENpm0i6Wwc*m9)gye0FiU8GP|Kfk9J7a@HH zK1379Lz=y2dw`B#$f^Sp0dDq+oVTBBjS!$0HASaoetpH6yEysW5l{V)K0Tm2RSz`5 z)u&!Pq*ET`Vc?T6-*hJRNPihSsen{hg+Uv6`GjO%I1F11a6KN1-)An^9!DM?LqumV ztZriRxw@cu-503N^HBLSaHrd46VQ=0{WLtIXE-6a2iY|e*cf*K%i-H5aUP@Qu!J`` zfAXedv7pqbn-(w4fi}%yJ~2K*t-T9ZCcJKK!Jgb9=jb!=#tS%a?`4S-NwU%;AmHHS z%yk@p^+C^H9D2SJG|T%QWfzWk>FvFNV?xgMv7)oR8BgVWE;6mB?h0sZoF5&dCGL4s z%kH(-fdT-AgO2ssJk{0C^a_M%`Mk_$j~3vwV(ge=B*){p&9$+Jb@8vztf%a8eRlhL zSy=|mE`0_E|JiGM(z}!p5s3u`}_2fzyRZjxP}Yp;!AKyP_w!3o4(a^7dY0#H;{j576<- zsjCu8V+X=U%d?|3pvYTVlh*|tLnE?`kgN~Jf{v5(w1bj7FM&Ymhe15JqEjw(^9QdN zR-7OG6>K%#b=&^fR2DpIw*AmspYFm)glkXlgVX_@#K{8ItPfJ`L-MzTWQhwh`dBWp z*q;s;EF_YSc*>E9nadP223{d>Ow)Q*U_8LK#?(uU@V%CSt?I9%Gr!Ga2_NDP^1&~3 z_;NFL!kN&y@(*Q^`Yl`&tK@SoU#rLW3sy~#GmP0M!(O@6NIFT!$JN_{ifU)ZX8q;{ zZ-LCxB_nn-A7y|$5_{Lz%sy*bpc->DF^2D7oqZe{Ckebd5f=V%LMFb?Ersf~^g4j( z);b|=O41S^QBa)q0cMmDll_|~LK1?HGix~WH0vDbMM{qSAdf7`dDGT9cmomh$NW8@ zUdqI-idf$Sw0_2WVZkbM#Ub2$@BojyEv|Yzi-`xQu~Jlvh3L`%ST-p0oQQud$Z#Uf z(0J98K3JMPIt2C9|NS4gQR~ryfFu%yP8#ITv|9)~8&ESU`;~T-6SlFl!N$o+heiFE zf$izjz+r$Fg~hbfnb6?GjH)3}WS|N60srpTfgWb`%dACXLY20*w#}W5{H1e^^bE_? zRPg713-~TBxLEO4H%B}C%iG>Qb zGal<=X-!A?-Z^_Z%`_p6_TF0GF-=i%4pDb^&mrgQH|%4W1D67VIs#aO-KpN}a_q|> z1J|Z?t8eLPQLPxNr&$nwHx1u4{z$RtpAkvKPh8jpu-F%KNeV-aw1kR;LlCKl;LuKR zO*SAG4_niFWAoVG->(f$|I#vi(SF7XEa$dwWz(rdC(oJ$P;Hb>I!InDR2dB^QNff5 zTzcDv?-9j!;%uvXQ1ONP+gI$&yui?ht=6c`v^c0xa&fq0+f7*Q*|NjFk!Dt%i{CAz z;JBgMjxY7A0f>>L=+K8dU5v&jW}S=mn;8~v+7{OOgOjZiDRSqF6Ds+yc~2V#_uoR? z^AkfaU8)6cxwrnKBS=jpPr(#$UTU`Vz`&&H!MxDG%S3{>wzM#{4-dA`4eGN5j*+}TGJYIFChOby5sFak>|Da2qtaXCZmeqDuPAJgtQn~F1~_eT#;Hud&QoQ1D*TQo z_v0F8cbD-v%+}O#!G7TcZ|A27KD0bwin+Q^!a`AYzFd_&eVwF5Ve3e|Mwll(YZ~Qs zi)y_}o3o?ngQ`|ewLp-kDLpP9Q-sQ6D{dhr0q&NWKHJ@Ip;Szg%#Sv5m*kA^KpE*ZQR+HA)92Z*}Uzmb`~Rz4YAyqSh%9#f31!q_Cj=st_G1P z9_x2sCQiS z0=y?-DNvj8_?|)|pG!Shc6F1vuOBJj{ToQo-evIN!x`6hTMs{BP;MpX zbY0lS-WJRAHiZ;q%*gKM7!~cK8046`t_!*3jjWtP7uo{)1DF`$eXXj*#KDJIFw?&4 z{0Bub7?*e{V7Xx}rEG!*k;t1a(cBZ1=nF)H&pZeh2$h+Dojca_3$~?`y_+S*-qVi@ ze-`Ebs7Uych&T1ijTWRXJhcpFvxZTUUX===2i8FSOjMHX>k|Cjb3 z`895C2>&FQM@Alf_l9dV)a8U$VY0)KyQ7fV-$}mFqU3LCE#!$I1A708S0>=QLQ8 z()4km)5rcg-jw*?>L(2+5OMXfvnhziL!xvYI8>7uPbFgIO%`HqmKy&LZMZ=sik%9&a}Cr@GLg&g~=2I;tGAvqK}93%>6&cJA0OtemOZ zNi5|Xg$A9ucc8^?3qGms>p9ZP7&IyS#aNJE9`hs3VYW&p z?RPcISCPwDN#g`XLJBohi1+wh9C*o`Zu9vhLGzWv_>fZnq4y{7Hccf>B|V_yr7=U5 zEYIO^XpZ0sk@1Zp#+ltzYoS_Va7eY|O_bIC>sC@xFtNteY~R#}pt9TNF~aR{<48l80pOZ(t#{*J zUCuueA-RJB2R^Ae%=hKX5)ra;uEglBlM0ZPMzXSxsGj!N*r+k&FWE85?n%`>eh#QO z#!?es(@Mb}{8yg7-NQdLUhmy&vt36}qgAX-e)0 zk$UCZEc0PX?9Isai+ABw&&47GBbU?dMOEcTc=KTyTQ|CsK8`6hxqg>d%=h+gZtIvm z-DzhTJcmPHKjX}qoaqx?qOYVc%`UuM**Nn6E;J?%nH9JWkAYtr>y*zoSdDM5l0E{w zT#bMUrgIl~QS0p%0Lsh>@G{C-PEjNK{%SFTM@zZ@9Ua-#c=FMzvt_!itj04IkUL$j zxV^AWlc|TRrf)7}t7mCi`}DLkeZ*8Jnm9$aQrarX7TY zO6`%_KiUyTDh1!29&sP@lpY=_<`yje5R*~u$B)U_>og}E{!|MknVVPgJtO3wncgHG z>r^L)AV9Xh)XH?_vX9b5XH@z*<}DXUg`2B0V!qO~)z$Id+lzLR!U{~;;Y6$h(G7it z<^j8NOJRXOn8l|)ts41h3w>wf-UVZO2{jrxM`_AGnV5bJG` zzg!NZ$mmTN6PwtH$OKHS0U9#)9i+d(p?n#VqZzXUYtf2X-|vHTL5}tOTqiCT6X@KY zXiFCJw^1QzUKM)9=G0GBEK_7y+#>)s1!hyL+xi=zUHqBUa92%a0pR__>#=T+f)78= zfU7sESKndlu|?A5|21i>O^^(1&t8Z?ih;H zLU!2quYKtf+r}zdzLn`x{nqo_c2ol!u4^SVL3oT!iRMokUdf~J3-u)&Os&Y)LP_w& zLW}jYx{%n?ethpZsDZ>6GZ2*!UNy|T*WxT0MJnV%gqo{QA0;4)l>6$q?Q8p*{+Z=n zQvZ(V$F7%l+~(E3>0rxGF*A_g2_S}*qzXL~ylp_GuYhh9i$H<_qdRPL;XT|>U%1CrC4wfK>;*tE6Q=p!oZ$M~ z&njZ907NXw$UZj$0;Pyxh{C?)r;$+c@_-6mhNY&}Lci$3=+Ey(%6VTz-fl_SO*thv z=+=mEMJ|CEmga;YSLG%Miz>S*c!V%*sy4DM2!%5riw>&I9xrfxU2W$dbp6_hPP&?R zY1rVAbsxC)J?MwDH0S~?jqkZK_=HdedH1VX9`=F3A&bvUZeM$J9kRgCN<$~*k&-`B z#@%kJ=P(94Y2HJG;8h>Fur;Yb&0@(f3RbZV$z`OU`g861Uor8-edO^KU&S3xD>dBy z%*DEs7+I3bygtF_wFRv3bT4ueWPPYk&!C2H9Q_|!3<2~kiCgpe9XxBHwi2k#pjd!rV$$G7K~^L5l>=MzZBqIIQBrN&_U=Pdx>Ml2_Hh^t@RU{q`<}Kx6o-^P=Nq`HWqq+ZnH! zTw*#zQN=FGV@{Gh-)Ud6)|rr4C%OCGmxGQWxs{_47&O_x5j?O2zL-6|7=ITZQ8?9- z2-J=%J9)aNBasp0`*&{HIS)L|2&aWCK&;c++uP%$T^JTQIs{$o&=F-O{#k*jwB8fK z+Ehv`U!rgCzCjmUFE}p2wo0)saSs`TdUx@u6@tTtqng$f~Fi=39SW zL>8dKhI-?;w%b-%ngaYqN=)SAuK5h?@ww*D{(~GJnHj}BZ@6BEE2}AGWtx!=Y}h>( z!*!}h28T^K)vNN_<+67fGw!r3?mU%b#U!WYt_FuYiaU(tW)(vh4+M`aza^w6kU2A= z2jhI!szr4CD><886v#j^Y}&_2x!b_#37d?2PcWXxU49WwW}WhZ$7R&<%>z zwcqorn@D7CL4G0x{7TTb5>k>~Q4%e~#8GqRH?Fhp{;1q)=7y{kO3eI%D)%k({G2b03&;GbF1ZuPg%%7|%b(>W9trVu%E};;P`HeZ zrbKkHe$9?kuK6k{DGg0!Nw;er#(YNs2DDpn;{Cw5>Q$l5wuwOyM%Nw)?NxzISz|DY^)>a*SOdwc;IdA&#n^4UD4b+d{+)uzc_qh&o%b?G2 ztsdu_M1D5*ct{FXvD2i)kHDAllFt{%Ip>zbIsZ4sa&jwg9DDrR?5IO6zpIY0Jmm|V zUGkDEpd$aK`BH6&PTdg=h98yqAIK)thh&Ksyg9Fv>(3rKQvfsb_47R1G~53{bh8AL zu>bE-0H$?$OsW3?6kE&vfAXOH4+vak`xXB9gou$o3qJ=V9bq+h0*Cu)+tY0(G)1*4 z@`{R|sQ!k?>G6#Q{m)R$9-{&O|2M)V|G_{sEAvVJ$4@gpnqz=zMpSx zaAY|D@Agkz3!%*a2OsJ9e~|vy8IKgB8a?X#nKbS{40o32S0x`2yqMBb*Gc^Mvbg87 z2!nR;5)#78*z_rc-#Y%UMAV^!;Qv{5e~Csar6AtFc=$Kh!@C8u|6=O@?+^IhFq;A~ z`ywCAg3cCh(Q!dM5)%jj%b{B6k6!<8NiX2QKS=%ctHxuut>|aaoPlF)W)2ptf(#Wy zpOTR={{G+G`Pc7?gq~vn!p^><=*K-Uk?ER>U2l@HE(~}1$4_2 zjx=3Gg5O zp7j)Qmy?4=`o^(OnvF+0MLAnn3WpNrroDIjYr!6oR--naRNq3y9B!m76%78S-`V;v zSz~0V;)e2~O7sWk_fvyP%XoQ*1fBNhc9nRZwLE)vU!_^DPZrEO(+Fg8;Z344jmi~X znwv7!VWTP`Mdg!2{1p^pa08UbO?s)B=fht|Rjg8%Cv{M@6iosiFA$00qJ=Ns2n`}j zW0MALao7%j^;%l>Gw|%%SF~E&KxFyc{qC*Q5EF>f)mG&F*}|7_Ydiz8iz~ge{esF^ zx0=6(&IU*%=R}L69gXTQzo%tvw!#!jQt|sTNaYoN1a&cVKY78`SNG$u*-I~=uRlAO z-Uc4#N&7_gMY-BKzi#yPz3%nDMyE} zhwp_s?DOS*iUC;7j351(hZj@&s5x7GLGv?u59gv`l>DQEE9MqdX$eE((PMU?AMb13 zD`Ipol~?>b;weV&FfZr!q&Z$kt=xvtd&cjIVInQRuozEr3uTx)6-Hp^Q2LD=;`JI;{a~8{MB$HJx zBHE>&WcmOK(L0RP3#E5^;&h^}*!9THU$!4~VJfu~2Hu+qxaZtf;c6JntT?8(KI#t( z@^FqvIr`vXd_R9kv^Ji5+7VE_nhZN782@-ctMrvT>=iM&moY9cYOjNk8q*cSrPQ3e z7V9A<&Ly;gl<@ zdBVp^f!MhS=rS^Y8BKpZCOt7cy-4T_@sp9NJ@PpOx*u*#xF04OzIR-Cmn@|77eiVK z7<>ZSKKrDlrCm&m+(HHh%9}wX#KcD;^Vi&~kKVJevmQ>aOPlsP>(ne@FwQ-J+E4LE zrPGB+9G;9StF%Ak?yRyRm6Q9ZU7H(q!qV)qn*tWb!3*X7NY*+1YjV7#qx(=EhRgfY zN2Y?IFQ=(Ri$x)o6?la|D|1-sUe*a=E5d_$o9PY5-%Oz^Q**>9yQ!4N@slmW>831} zHwFtg`3CoOrG6Jp(ug+vK+)N;HYHNGNPJo(dMu2KyZxrYtJhf}`NCF0ux>Y(40!R? zlghK|57y1u+VhnxYlyoa>Mr3N>CbjNOOjY~m*1WFWc~%M)Ei8x{UQC%_~KJq@r#Lq zw0lYN^3z@iRc4S|8NPi9zAz6+3Vh^FFtPb2hpxoX@8Znl>tIyo)dGLh(|>VJip9yP z{CdQrS;^0U+j5)sytnyA7>R6^fn;SF-|nHa{O3K+nhA;Lha^q1AJ$d@mJ?sGⓈ3 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Ȩ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 V7|S$;kre@G3XfIf3LhEz{4dTL{el1h literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/concepts/ui_form_add_part.png b/docs/docs/assets/images/concepts/ui_form_add_part.png index af8daf98368cac57f4a9c1fca71ed3f568ee8297..3f2cc70e2231864f155d90ca178c279585abe844 100644 GIT binary patch literal 50894 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 diff --git a/docs/docs/assets/images/faq/boundary.png b/docs/docs/assets/images/faq/boundary.png new file mode 100644 index 0000000000000000000000000000000000000000..0a0f8a7f378f769992f3ace4bc9606b55d8e9bfd GIT binary patch literal 29842 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 Ydg=YFl$Ue*0zisAUHx3vIVCg!06tTm!2kdN literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/stock/transfer_order_list.png b/docs/docs/assets/images/stock/transfer_order_list.png new file mode 100644 index 0000000000000000000000000000000000000000..b371ac350a5b62bdd8b86ed74a1dd21d4b382e04 GIT binary patch literal 56809 zcmce-1yGw^7cNRmDJ|9pmjWfYTXAb4P~6?!-JKQW(Gxy9nXYQUilbvMm_g%KvUhCN_q4KgH(NPFd5D*a1CB#9B2na~*2nbKsUp$3> zW54(&7ykCrUR=Wo0Rf})_v=XlJq8g1!dnCh&7(Va74Ces{keO{tD2TvYru6y;pGG(r$HPT6PjVyZ03eS@p<- z)AhUkkOD0+{p}+Ba6ymZ`P=`*MaG8ww|h+WvO5LwZ$E-G*x-5Ahc#zj>U^4iW=#_X z8wBV5NfzP>jr+PXbA zzfahIzF9cQxbX}8??(@mftUXh_Tw2o#Un2eF3vyAPS_aZZ*N5gJow~qxA{M#|0gy; zTYrB>SfXH4CTh`n{`cdjJ-oU9<(dDX>POn^e}&?X^}j_U&Kh}t&?zn8~Q6DeasK)f*!~GBQ7)4`Xc7+f7Oxjc}6v0nV4=|}FmBP1OoMD3>|5Hl3y%Qm%R|042|W$9n0rNuA`#=~W%fHA$R z&Yo6#(?tJy2*${nu3d#IM7tMLi1k0?nd0b3GL?fMs$__N+4`YU(buo0<5*wGm+o9Q zR;xdZfL>W`2KIm2eUfKREoITiAA9-Y-2n!#OH|^==w;3dq<V@7~?IDCO_z}sdMVJtDKl{gCK9$VmiDiOSnUfZ{)fl8{Y25&$3$r=1{jIC@U6OhU zyv!V@PQpE<2r6Qd^Yg?cT9II4Arz>LP?300j#q z6R45~C1ZGgtYf3I$0t$W8nl>e?)5nxJ2S3K8jBX|$`N!kHzB~*0Vev8{Nm*}wJczC z(Mm;&RNkwJ`;YGJ69^RiIRPS|4Z`tsTS{ms)MDTsn>WDs?6$RK_SGiDt6GhK_Uvs2 zk5FO^(pv?{)by6(Qqg9OaPT?f1jW z$@a%uheT3(lEr@Nj-@|O{!|jvApvqOozXCHhMF?-98u(?e~Wti*c$msg{svm=H!dF z-7+mI^w&?G^;#Z1QeX}irLt2fxG+Bo489-(-Yk-O4H58W_`*s~=(-b#Y>gk9^pG)Q zUJE~*IUTAiAdmbCaJv~&lM3v6@LjTl*;qQTb_UYq8j&Pojn2;|J;Y3l^UIvXEs&D3 zX>HO2*r6phM_bxe4&@!!=!Sr^lB}raM}84B*2BlYl8TTQjSL63a&KPcz|KEZ)v8T2 z_|`bb4~5-N>QDi1q?r1iM|K3_?l*q!_KlwNe-VrPE0ldv3HviP@dwa(TGoXPd)8nu zQ3`YFyntEz4n`)}{UJDIjR-2)l;3vTvnAKI;Y~5f*OYJ4Y9(-ObL%6N>9}m81m0F> zO>$dM)v&66$CuC^i^Ej~TihDCX*3$`T*fCFiaKI6%<`bP8Xgf(=n(T`Q54vH&1#R=R+cUch;>hH zgaMdLBd&PZRNU-x4WHx@O4n&Mm;A|y5<1heqvO|*?AF}(QTXUE#;bo2=)r|wa;#PdF!47>xYuWeo~)H?UJFB2kHwhKfhi7URqGinM+5H z-n$!d(W4f}^#Q-T!>giv8MoqxbqpMUkK!-)6?>b5yi15>8;;Zl7h@u-(KAoZwE2Vb z2sgU$3z;OsIkOV=1OKm`7ul!pVdcJulU32Jg>jOgqc-31L!ZqaIi01uxY;y6w)xc! zr_;zRKMg$-Yj!TTKw1+nvA!c+BEtMrqAi6#o7AV0;btNbDBd|qPCA}%S!-C~;~{HL zREUpCyU+Y%*m=2+-_dJa0{Wpc5NJ6*T7Ro@jXX~+>+7i{?2}Urcq=$Y90YP+U#ML8 zz@x zWd&s7X0|WU%$H~Vc8(SezzVC~^0E;hEzc!M z{vq@%MVqP&jv8O@(ub}`-Pax+*uc{h94uDX5c)G_oGcQ%ZMwdrNA(9-w5117Qf7aZONuc_$vxy-dZ)J&p$^&G!B*I82o|7%2m9_xS zSG4-MkCBHA@%zlF?iqdMa+-%$LFJ43k+IJpp_p8N> z;eUU=8#nHcvsV9Td%qVlrDSp-dUJ^%$qWc3SPLCib7P5++lnH1;yairloozb=gRk} z@L|tyfdmA~dSgeKgCDtn-DApvrlF-Xa<8XT*?JItl-5>}f%zEl1HQDV1ax#%<^`=9 z&!d}cUx%H~efD&Ub1K$8J@pG2N@rqZw{P=pEiU!HoyL=K+rz7EqvuNhS)%}(Yq@(~7gPJg(K)?-28=z_zF z{p4i`GKb}xCBL$_6%md+`#nhXt(?!0Yq)NT1KpH(~F*+u?#_o9o6Bpx~Wnkp+ z_T1p&Z0BuFDtqVa4iNhw^X)%YhpnY0l~WIxt5DC^R){t=__hj(W)&WYjrB^pc>~7 zEBSn;`A6(un)V>vlzMz81pb5wpQw*~#i@tCD6<{L zKwAA7R2wa_n;@eCMFAEjj-<1UCp>CjVJ-5W8F&*iA z`!^d&mWM5iZB9}URKIZ|shtl6+iGrL)I}%#N-|rpbJ&Y}Qa(U|Hn0;mKX@xk9gLs( z^7M#gaK&D6j!1@Da*mJOG_z4}WwG{YutD-C+C`~rNdklXa+cfAe49*o_vCGm#o?^0 zZr3|!B0wKvXY`}y`?@x9lVsj5LK-kG^y8%0 z9j{M>A$!bjFE%UR@w8f69(snrV+?>@F%9fhng&R`*8gBqSuJugGtM*;p0_! zV{}^~c@9tYeb#cF{uWxq-%RDxOE#SkzDtJ?uLHABSjQxUUy7W5Kvupzoe#B}3pH0k zYhv}4ypj%G()YUy63drU7y32lDT@_OV-aw7sD&7nRp+BL>~mjs;21Y<=pxuw|FDSH zVQdY>hmmY5J_`#{xm#OW@$xOj-_Sa48CcLO98-G{BP2AtAjI~#UqZDS9pqGS&cILp zuD}iD)a~d1o;24ZYo-zlv~4RxlxKeR=bh@%DrEMPGyHPe1ijC%3X0 zS)Pf3U?yG17fQ*x1L)t;VIMP?ICwXntdUlnKb}bXWfrvg&YY{(rC32n)La-+dr;Wf z1*Y=Q64}r?u>7(cza7mr)$i{#ojcA;cHNS4&2dk+`*Fa%Gd^I7IGxC{A>bon;Qp?V zE>A5i)$3*EZU+n6$QiWNYA;pYvo-HFatjppekYzbc8as-nl3FI=G@MLcCkFZu~yVr zcMz=MTWxl;=;lQ;eJDM^aJvt>->H@np7!}8i-ya=772S>?KM_sT*BkR$FqmoR>2&+rRL+2JE^eu7E@B1enJvzDPFd#;T6n6x5cfIPJ%G? z^H;5S42HekkbMk1Ic!dm;O~D@<`qp2YUvvH%&T)AGfUG7he>8L^aWvvaVs~QHN&!5 zt2bH8qutFZnvaJmn8!@|+olokpcct{=7-e(NB(Ob76IOF=j(P9S+`M+;elJhiBFn! zsQIVF1r^p-zx(fzU^WbOp{x1>zHjT)CHGJ7Ma}y8PTOiGr+8fNEsMQAT_L0_Ei#TM z1$5Hm4n)1N@_>n0T~bf+7zifRx)MPR@l6+BJ@wzz2}KGV+&{bkgU)9V$@p|xr}SKN z+f-mnZ48m7AEnZ)QnhbNhFW}Cc9vTgm*s3Tsbb)Hba`c@)BVnoO9US(5#Xeg#Y*+r zJ=CXI(5pz!nF+w&)?hbf$4>u7_GXbNq0Q@CESU2VbTPba71}#F+i?$d3&||8=F77a zJkQ=ai%ZHg%&#lgVF1`XcBPkpUsx3Q+S8xJgqE6jPG4c|ag#Upi8fX~VLv^)Ysa3o z^KL)$n5>QXk4bCi;Rlb!`lOY5Pg1%)Sck+7t2W{e61=_36cEA2X6Z(ED}8m~kS=^fro9SKfa|9I{&yPHHjCKqTzkKhvmHq57 zki)lN*fsaQeW@G1NVEeO=Fb?H+m=ez>ptD@8>g)re)LcYS!}-@NWKt4k!}_!909h} zA6CQa4Q8|6WiVOssm+$7#XPuE-o|k_nj9lA3lWVS2q`k?uxuWAB%x2HX9ru=%!Hat z#QXg$Yo||oj$wu_)F=VKXE|Dlkun?B=$#bpt;J7t zt{xfEt|X-2lKWI5E{{-6^OcXF(e>eqTI|TCyT;*Va|M>Ps7e{HG{bkYv#&>~3x9TbPr!2*og zu9{s-SXtO{*5%X!0RcZxL&;8D{{bHL5il#0t?VAlZ*n?T-vWWY!kh!IV?e-@iwhGU zA8O-p#I*bur)yKx`2Qk65+5nx>DHPQMU1#M({!hu4g+pDC1%Wv`%>zs{}~f#fS(Bs z6{oWu*Ol|3lu3J@QT7eVuj)ivuvgDT49nCkxshdB!L7 zf1%uDP_AOAa+vtRjsNh=ziRj|;|Txfh~~eP{GZ=cBA6#Ddycz&^B*dc11AiMPnJ6E z$Ymf8PR#P?tI{{PBlESi&GdCRxFp)JRgbxA4(Oao@#%-!_n5D`yBC;a>mwmWfErLe{p^HcJYqWQAS6Vh8)f_ zjHZ^V-5f}tW&QlEH${RZ&W9(f)n?b?d1_UEtm{*#^Qikyn%w{)a~cuh5D1%J2EZ@l zuD(t57MVxBe0CS2Mi-*%MVR+tn{z7kiQ!$_PAGA*UdS!5(EAO7g4uqp zQvMO8Po&lEndTpI-8V5S`9DEo6NFmR$a4f}_rdvSaijw^4&HGIuL#A+v}~Hc_lnoE zeN{;ENY_>{wza6j9L?GG`0(VxN6^yJmUcAD%Cbtg?}qvZxo8pS+;dRY4(|_P&3&7W zEoalP$fRAcdA8}&T`yRpm;eN4y{Po=XT8a0kRGm&no9L`YZD0g47%bY*D@yyYO1@! zP2lm%nsk7q99#M6H~+SF0QPT_ll0o)}`#8Qy| zDg>A%j-uCid`45Pd+ZAMBhA|=;>UjXBHMoKHooa4Z;_eO@|`o_B>W1``G(=b^5vFt4<@oeP;OZ2$WO~z*r5nV&&)eZnQsPQ_^t>oS9fW78-P7jqa7!Oj6!Vz% zX!W?`xwFU>JwUV0Rm~TL+l1`v=Q*}&e=K)r{cLA8_VARpY^8OIZ~SrMp>xEW;ME78 zl1RUs+RIZqHBh1Xo>&$=^Cd+f>D_NCS3J!cmGzEI007E`hxJSY54;QXY`4;u6gawh z;-cfT4ob3n5p}~J6e6drL9K@MR{9wkgIw!06ry+2y+osm#4bE=mM%Y<@4oYR@a2Ab zQLyyY{m%FMbBKdPy6bLwI5=~;U$8BRGG`nr=87weZVcb@OzJ<5u{p9#(RuqEW0V}8tkkl*+`WSpRwkYU;+@+20- zpep-{#KPi_^9-JFpOprkLB-Gn=i#<%*UD&RUW3*mmQ;4??4Y3ZzHTp z9>1J(&CK-%efsgpDEiarsMj`+MMsaVix2H)QC|_Zmb4l>x~bXctoE+I6XZbabq5T1 zB7tnA6r@em0ZLG!M3Dxep)pS_lAr(p0JCKYCeYz2&e}$h(nkL^DzF2Q z64aSeA~{STv!&Xkj>|@G*tbCNMA5QE-LW*?v=_1~RsKCsDoNTUg>E=enN#xs2ywgw z4(-1ttFMVGdDt?}>+26KpqV@~+@k5G3E+@c3k7w!eQT7h8@B1n@HLE= zCY3VWJx^6^e`M~yqP_xyE=O8jU&q)&Hrn|<@}vsbR$jFoUV7ZOL?M3M7a%{gjQeey zYeXAuamD!)$DgQYZ#OJ6~ zmj;z*H?FgxjbAL2iO(VssOXj6*v>7yfV=|4IQI{Jrv-tSv^G=5Da+bX6Gex|l891QgHn>iZD;xvV z>06}hX^HO4t`~@wBo0vky_|G(-gkzP(iOI@ZOl5EoaRaSk8=Al&exhe3!SP_SgRNM zo}?0G{rbw@vzY#Aip{I57ctjHj}D@c*)=suUB8MB)?Z(uSDTe=?D^&7TKipQc2e}N zF8w0YyZRq5UmcV(zx=k@V%V9q_x5^5fPhWzHvO0d*l6Ai0tp11m49#c>l8$Z#?JHX z?`*xPzP*(WMM(}&EBbBa+SK_W&+2PbQ+9Wufg>cwoJKkVfFb!4FB^li7W_mSPls7wRf2-D3M+JWrO<=D;0AL@ zK3I8ser{jwijbCQ%OtSM?TSrj|gPJUJq zE(I3n@d3*oJ+0IeKd<^?UU1;3<6~l?va^#qHukkJxywmZ+sZ4X_DbEwVY)e|h_fjU zRF=e?sG7W6Ml4*C&D~HPq_oD~^$`Tx*fy_?s}Q0$0fRdq#(&<2_Ku2C#9qq)GMfnC zM+~wB0}}6U+|)aAVI_F*qcG1^wGNwgpWFJX7+b?qI7iRXMB02h-EO7QD?dLD4J?F5 zLttre$VA8-G_34N z=q-qXSoayVY%}ZOc(HQsPdupYQp3e`RkeK%IScMDPCcH@MjTf1ZI?gMsRaQwn&sL3 zRl-e_RH_S#O_}Q^vjnegOlo+O}(qs;z4|^oCRJwda>dMYgtE%MU*mX`24sn{_!l+BTmIhDTS< z>#a${9b(dgTGFxH=DV$~o|%W11?n*z(XD_89#U^>2sJ!ZI_aFANClf)cR2pu?GWVr zpCbCczHO0a{ZABhH=cd^;X>;L#d@60)!h(DJ<6#3%J>7$IH z-eVElsHj&{Z-@y&)8yPCS|T_U>{jE*q)N3~syb{o=MN@O@(JCSNlKe9di<&rI)Y8B zW4XES{VAEOpsX^d&PQ|RoPOzv{e=d<+}-SS)EXP~ZOnCCg}oV*b2OtKHZ95M_W46_ zT$vAB95PGWEywK!y|zuuEsRl#T!=l;!?z@QJS<=5(~C~rmI_Fq$`R&{mhe0EnWz0^mh zkK>z;fKh_`*~F_6MQ z;A|RjfSk@7Q4cWBf`CP!ee>!Xo?a7n_?G7pGq5zeL`{?^o}Z30p`fOrYGq?nF66bP zJ)4KoXgSAVz|dt5KU;H}7+r$ltSsIb)9Qj)BklwvZm69AmcX}wV&lm^@esEB*7b&#N&HG&j zgwTMA)^XR<;^w1!yct>{=cA?iV58xYC6~mc>%MfHkymt`(boF-be>g)xMSVB^8BP933#(&(1dXvPXk};Y z=g5FK#Vft<-Ujl0MPbaXv7Hx$*GwocCK-;nwQ?RCf5Q7Oby|%tm5WMz`7d8c+tMeA zS2-TIBwY*LSFhu}M5GqQ)9lsbn{n7cjh=1zXv{r3SE0S72an_Uv}_J#7Pw(ym{j~1 zmV6hoCd|*EuY|0~a~=$S8w*;8wgJ>%0pG!x#6g5cBq9$oYfE}Kic{5276Y$#LO_r< zHLNthD8_+Dn9JT;Q|_}26v`->`7bi_8yr4NNN+|oq$NIFFIr0}onj}iUoEJaR!LPiL@%SvWj%SRJ^bp3|$Q~_QwAa<#(h+W0v>I3t{mh%1X zxNV23#zRVL16hXdOwYaY+j^Vn>lzX**Y?bY*wu4gzNZbPhl-&fw14Ws;Bx@@?mjs| zs&iQn*!r{A`$y(exPnD?d=ZD2s~;ahgbv1sZdD2@!Hj=U&%76X**QT?5N2cp+y%Rv5#;{*i3yA7#sjUYJ3$jUMGyn@f=Wb*Y!jak5CAb9>mq+H%=#eCtxBix-<;yEJJVoHcwzuhj7i;G_F|Gjmu5Gvi-KwR4wST$6n zthA=Q9`${Ed>b7)l1pEIEnwwWt8m&f^<7>*C>Z8V(+nQgq<*DunA7=ciI%t^sZgU# zHAR{VH~cntsDR#@{fKAlFO+(-D%5o(Ft2vNtelz8`}C4yp+5imwoh}; znrZr1#iulUAYlE7`plK~x2RVv*^~&pSDQ3L#&_WG0Gb#OcSQNQR}(f%HoO+2x>d0B zNaYy!Z-tIrejj2%A7YCR3c{yWmf^qkRR0%{jnS#|w{}VYKq@OYL7e}ovipr>h}1f0 z5B&2Z%gdq;<@J`(Rk5viWO)SX*>l?$Y(Ku(CnNB;Pd-t53LUvX?78s_Aoo@2SZyMa zmZsvf>noNv-41T^HK6PW(wcfWs<>?bxCBOh3XQ zn4FKREKC)N1&v(EV#?an)UUE{K8O%!py-|ta~f1)ENs(EOU8o@vTWbz%4f-T57 zE~G44DFa>+lbkENCOi58vVR>M!p_}r(vtaTJ9?GpT%ud!?eIs-;|kY&TgfkGjdiwr zrC7Gx*M^Oc8n~E*DUI;OaB*9x!cji4n4+3J5+4q~bW*>Mkt)lv>6hnGxtr7a#_!7OSLolFt`AZJRLgVM_LE5Zh2)TszD0?W@}%Q%z~(BjQa(wk-lC!hWZYct$0D8e7@(GV zhKe12-yXpa6Iz08_wZa-Y?=wIozUpeLO30oTzer6Rd);QxV9HBaG&5Sr9WKAH0qhA zfyHx_KlTkm&tO7HZIAbNA|dRUKP&QY$=#@&#u=lxID2cYuwpw*y4TY85u46X8H<0m zoV4fvBuAoR>Yg__k2)#U;pyO$up*hUdkc&$A=g;<5LvzDLlqik9vYTu5*5s!-|bOs zI3rn%GD>$8z03bNQP=OkKz@rFjqP-ev{RzdF?#njPDY@UP|_)yuwmtdaSN3Cg|A4J zc2(M>D_9AVQg9lsdFqrEMSK{O*lR>89Z9^HC_u_EaFRhZb=X_~8c-53(Mx!KZFkh` zcO-A=YCFf+KWcMe$y%-k<6a_uW28eZ_3mXfh4~$ilu3Iw;`MD--w5-p)-jagVxu)Q z@)1cYcf!15lfeNuPS=l)%gM@DLF&Up+?+&%QG7i`!4mL}N5YREKO>a8Uu`ATk{z#C zt$>7AQ(j(OK9?(1F2ASBm?u?7z7GI!6Lf>Nuofc(zm)HyI2^24ErhQ}(Y;F*Ob%l^ zl(?=I^+6tnE<3?Sv2XhLV%Zwi2gEI1A0`x=*%J+(PVKu}%r`=c8=zr4!1016_$rVW zCrF|5>|mb_#syYw*hQM+Pv+OdbyZ6yMybRw_x%if3uP&1b2Bs44)iy83S1+ZN%30p z$$3>n!aSZt#FV-#tilezEG_r?ht;C)Ifb#tqOoxjlxIqDct*Mh`r_{g>q^<8z`Z%k zkDZO?2@wX^fD)2^{=GXKB^z>hKBu|=6NH9adE46@`T-( z<&_M!rd&qp2(Z3}K`yd0KBBz=z$S;e2|79t8EnaRCmm|e;(giOmZvxX#oz{HSEyPl zik=^hY?-_{=lzqp5|S_;hrO6Ht@ zfY2dn6NgI9RF3CLt}WiJI2n zo9t%kz`cp{IkOWF+d-2^UZY!E--rBYHzDk!@{wtQ){2JD4eTja6IN^kV7@v=-nXVb zA*8lioh)H4x5G{o6$LE?^X<883T|Wm{&Au>7v1U9MjC5jLj7FYge##YD^jIycCK>p zQoVwtR^$>hGk4jn3v18Tpb3~U_T+rTW*&~I){a(af8yFbGKw@tbOJs=BkEwOMw`;e zxOhh9*0Zh><4T|NI^qaGdVZ)+JD~kdKY26y(AQL?hVEuGnlaOr&`r<_ifEOi!X}m< zCNUG^6HG2;@W|`2@^KtjeDY*>b3{O52N==Q^%rVbL_keu=j&BsuyzMKTOM zGT6tB24AdpMoDgAb5NJ!hs&11SgzDM&Q$xlOUE@7q29@Q zcfmg7=76LFtpfdI(N_n)rb-c#-Mz{VLd$9k5G>@@nV|P#l}u;r`x&7Q#R#I#cXh+5 zapP@mPD<8+!u>Q`-8Syp>XYvUW+Jasw5GcXjZuagi9?XLzp}q1PZgxvqS1?)udh4p zkXKOQyFwE+8%8%1P^((`V#0DLr;OP*eOUG#QZN%X?(zUSy=vLyw;Pnu6{k?>v6GWq zCaIt@RLjRv!8H-c_-YVJu^Y%};T5f#*ow(a9a|wT=|#zCK_HbY%WuA6lea^!0aPtg z?pcb9_x%3T`5og_mUxkrFB$m-3A$9S2g8Up7oPR>YXDL4)Kcv0HfdQ9c0#(*hKG^v zsW1?@85Y>tRO1NLjEz+rNki5h*}mLNrlq5WC&$=XJX+pc*6=i-FxUEO0K+5M`UWjS zNWpxK%m_+hrEp`JC{FUIiey*PJ6B3&$U&sUt}8x88|uFf+qLn&$nLby=?$FVs;auA z=;;sDNl`W48Va(gd;oP?PE%8rDr3gnw2O2PBa*4nanw^#9rd$jj)c9U3X>i#f<}^3 z(1wCH=8(rPTfgL9Py=Ng%SW|i6RK2YK&LpNMHL&$@h;3ir=fWaM`-u^Rwy%Sac zbn$y}*=R{=tR_KSB56=(u+=;IwZ#Hh)x^{4kll%e+olaFD=-Z|*}eJEUc2ewJh`^p z?iHhjMv&=zpL0e!SiFUo)uBaI7F5c4Q3$E#e2X$oX&W_tg>~JNkCW;l0f#YDF8Mpzxpc|7Ev^ZKD_yp&w^{tg+5)6a91@E$WFK;ppBfYF44BPS@WCoJNv zr^znu?RM2_=e%raSmVWWBs@zBVLF4VCm%G0u>qB-UW#L{66cCvQ3hjPTgB=1itAKR z0f)$W#EjaP7z6=&e~sFCpjd?JDb)=0V<0=_p|-5?t#!dmmNw0CdsB*^O}=8{RDitfk*8w z{PHYQq&X(%F>SJ0L9XsI6E3%X<%Zm`bfpheEk~QC;!m!spV?ovs56A?Ax0af?s;Rx z3%L#4(W3ThxUKzx_Y zs;LgBQn?a+S=eev4J3k@Tu>VYEQS5@@}>lthO;XAaj7yAS;tpy_OMkd#d2v`KSo9e zGJwK3@*R;oR}|;Hj>>Br4c>O{lgtP-*rSfcXerN zPkt_g9wdhtLtmCmfd9^9F(YU(k_1>)d`5!=Ol>WvO=L&q%u}HYp$gk@=0Pl?3 zhs^`08K1wjF^Mb_I50X-vuF?{z?~r%oppD5u6WLIr^s`nkuy#sQPJAj?z2pCCm3y+ zFL#gmQK@nV)+?1WZx_{^v3rq%p4}QX2YL*FwZrV5U`rRGxbda_lJBSdBWD*LeF~uV z6OHF^aUspuF3LeOl5$O@qKd5Tyjfz}m|AAK&+5kNV_oQ7`uvz`Urw943-5MRGQ@1H zir}ctBXP;r?)`v9*V5P!0BGX`S(--Tep8hR|J&4;gxAv8`%%7;vl55DhWR@M%9|_? zx>Rq(a+=y2+jw1l4Es?vkR}h^8LYm=il>}^h6`BBMYp@U$ifZ>|DZ)yRLdY$Rd~Pu zT#*Q_MUSw-A;e`2s-jRxTRLWFn6rYHyJzJEuet!LYI1(U zYf&onE7Xg(3CTQM5;C3T(#%z-i(Igej)SJJUYW-2hqes_>MrU8YR0^yB~9^IIvX#A zto_QYnZT;6L8fQ%Y@3rBtLgA@W$IPSziZ@vu8hpbhD_;a|R})>MqD zbV48Se4JXbS$Do_1Ue~N*3cUosdaWUDGb29^GQYg96xcz?&qVG!;Z!4+a$AfS|ACgVazAE|ob3G_X4~Ix|;-%Lq%96Npbvk5BA8_L> zNg!7IJ3LEo*WX_Z$nP>QT- z2EY)AXlv8Zx}WEqrR*uAb@b-cZ#fyW;xn|y@Gc5hz43j=`$?h8R`OQe&T@zMwWCd` zDlHkxR36FT0AF(P-ka-u4IHS2e4L|g%~%##Jx}Z#1zTE#X>{KDAQW8;xap`P%>sz= zE>|U|E+*Ij%XOD0*sI_heb#cGi=U31x_1fF@O16V*QY!QBR${nK)By0#TDy6TC(Ec_~7Yc58 z9#9!1UZgOf0Z$zl%eF)o*ZEb-O1D-^fj+X`$flDYt{?jZ>a~6n~AlvEHCZkSfC_bV0#D+pu{l6s%G_>4;gr_Q8=|;@wLvMWrlh z86O57hqA<|1KFjidJy*j0$077-cN|w@JqwTvVw3WQnt; zU-@wnH`2E-h}%ck%7XB46{`uymocEcDCO4<-KiwdVR<)n{Cq1G#B}e2rJQ{V4uZ=^ ze%tXU0j;Tf9&ukPWaeS&r3(V0`I@;KQApoNQ>zEF5Kei>u001DNUN_A*KRa`9 z>sqSfDwa@ePDv0bst&7Zg;Do?y4Xe7gS6Urud$KGXcN=HaPkAG^N%EUi%W3~2tB^@ zAJ~81s*TwH=INtxd8lW4gdxX!Zn67y&&1@x==ulKnK#6pe+_{=J4~4#jJBDVkE`e= zP?{X(bYZrH3d3$H^D{1O=rDSbbo+S`CrMH#MxkvQDtDy&7wYLA;T3l8H zHPA8nG)qPurfo1a524-TI#2Jhf9o;6KD*E#U#hmY$uT?cn^FX;;YEf<%@AwD@UQe2 z5$XfJd100JyeWs{GOB&C(%Dnxn)L=o!q(h-f)PGh>cM%-q5=WKP1BqUPiZ+Ud2mwE zZk{u>o-L3K%U=~qKu=?q-S*Gl*AFw9_FsLaS`NEKH#ftUl$WyjAi-tppqay)cdHHR$&-6-l@47+%i- zltWWHcV6Y@`3=S>;bhJjji6xcwzBEmd`6!(A&T20zi$SUCQOp)ZL_Rj;v9&Yz=x1a-$M!dCIdy#K8Q@O^V45C!JGpHIsX z!5(cJbcF`R_No}%A7(CwBu7HXX${Jl#3a%KZXRe>-WuYdBo=mAzjFi`Pb9gLu0OFu z-i#v)nFz#U`++>$+NL=_H&kQ)P?lOl$Vp_L8FSKW#5Q5 znH2N8B!~P3Gp?Pr^&Bi$q5{w2PJd&`1pi)jTNcL_`aA={WSza|ZG7hfw*vd`%9{&o zf;K8&hPv%IYa;akc&rztT&DUE^&URZsl1R%@6-SO8eletr-o6neJEq!4QG>L+E!fs z=Wg`=Jgn%mPAeJNt|wnC2$VaK#~<^RqT@j)EdP!mP`ss8GX-IW2F& zsarz!CpAxpXcITF@|Z~Ze|aJ+{vK!@B<#}HgpuGoPmY*gOLLD44-J;$(yIg{@MJ-| zodGy4J*(1<&QvV3XhvUR%gz~L;yRncHv1@LO|%qrv?UAO^FtnTmZ9RUKvokk$u&tH z7gKe>uq6y%VM+D8CJ`Lzligc70)_(ulF~xSaY<G!mo$2v4!xT#lFN7-hU_^5HO$i1S(Bx-kGm26L@9g-d z-noAiWlrza#sRH_Rjp(w)M0C}Wj1atsK4!Yw9rX_#1hkv0NOFljF|rA{bzXCFUl#` zGcZoPkfHj%96||KwWBw-OSzdl9^c5>Bpl1gInGVDBvXyuBbiS-Q&`GYi>+Z84V!rC zG&0x9&SBlaxf&B6KUC=mM3Lb)-i~`>%O>{DC*n+jqwP}RoIMHO9pln4pKtd-HV#70QobPn{W#BSk4Q_T;kfA~@ z-Qic|GUhOw#S+mnY%9Ij2dFuW;Y43mKWIL|dt3gJj*6!LE6um(r}rP^JD+9yf8c5R zAJm<7R2t=59KwB2%Wk~%5O_7u?CR`+}7czKhs`o|p`3gL*TT0+p^#nddEPu<1^ zTof=*j&OB3U#dvFjXIw}6$=5ky=s)7kAh%DD#%%j`X$P*8YlpMHP?@a0j4*DI+W_( z7IFZgjm@2Ovr0#`P;|Tw2M`A-08aW(J5}ZH7cq%1IWVa%+EvQ=wup9avG+31vr?`Qm#%ho|^uqF*j-g=dqxaiGCyj5b8UR#D;F8ir^x$}!mg^a}N2m~$B zR=HMCK{`Qpx^{!CYWB|5R0LAvC=z~ zbw2?3>06M0gDjr>t>2lb-;=F4IdBCc#=@?1ey1UM1TMc-LAHIcy;#CvpPY|!Hd()l zx!ZbQq~~!V>COSV(Abz;zy4}K8lJ7nSmjic3+KNKQ%J*Q+yrrZT{SYFKNd!J4Qb)6 zjp_06mR8Y!+4a0XyL9724(>6m#`Owtho6==Tq#O#N1#)$Z3n>-2jB*qE!^eF5grfc zHlCB_zC$p5g0mZq$DA&Va>MJCMAxwWCHKIuB)&+Wy0>09?a(aDTBVd35E7`k3?g zFwTIB3lOaJBbAY99Nm2p_F1X1kWfl69s_(iWt1A%D}W_Jr_vn?{2}e;co_3RJy0+a?#!K!em&7 zR|K{54_;b7Cx)W_?JLQ1Z8}yBH4RQqdRV_mzTBp<6L2H-5U|ci>W8<-*Awbhf6N`> z?)K;m>oiQ;;-8z*A%A|lIU}r9D+G)VCCg~NCTw9kc+(P1)dM{CqQxj609J=`Nbwwf^gpq1B)2_s7B z81n3&KY|Dl(h@IzWsT9454D|cs#&926I8MKZt!R_UA960f`;Jx$~~HMErTI~Mb<|+ z|A^ti9qwd1E5Cd2u$m_W%h^KvQN+XbvYqZv_fyhI%bUpDQR***W5)F)(2=&HBl%m5 zOJTO;hSGQY!fdL`C^qmVKyk%@?C#C}UYe0uou#zw+YapNZ^iM;?UU_+r5psVytPIP zPz^imMCaqqXnyk5_Z*mah_uJJDJz_ooWHzXeb4O>Ddj#s_4baWI-2bg%jv zR<>Pi^_Y}2>seBhhsr{=!&UM#-Hxv0G@V^I-`4DqSvrO5$+#xPE&B|I66LMr{<{rDS5VGK_Q%b!#Ka# zYgn9ttP)IMvDAP;v}b;$WB@%RY*e$OqYzM$=^xom?r$%M77S@q-vl=d=agxV4$x9~ z&|4=An9GewXxc8GGkHQ)K?=b__0xf15E5iv?${m-1GeQmL3ZaLgR&l5 zoSxk66I0mBKyf;H+EVoetAqj2(_JQH<30FfpM{lOkV$pZ zgIl;zFypdipBPv|j@$TO5AMi?*Yyb2Rk}Hfc6wo>%{M9}Y0VW;Nfjc8Sa9D@zo0N@ zeTquMID#o@QQl3s3SU$;o$dZTLFUyyX}#BgKGgbPOs$d%a;#bKNbppg!c2I}&+J{b}0fSt7VkM+`bFUYd zW3F9PaCt2*W#LH`4n)=O1OObl`}5v^PiB$4t_E}8G{iPC{t~RBuDP+xZ)oG58q$2( z^3Ru%RXgo%UOy@Dq?Ce@(`qmc4L)WHk$c~o$-T1lbkdOCHbX*p<*5I{VQwO#e85C| zuD^TxCy#X>3GdDOZU`xlDvkPCzSnILF%6evD96*af&CGYX?hWQy{Eib9!B+DiMV5L zrgT{hM#^ixGL5s#dXcDlj7V?{llf{#vIFH=g`yw)C7+Gn{TZjdR^gt7ousoY>dMox zO6Rxm>j>$Ec$C&H9NNFpFutHZ(UE@@g#AFBW;~<`{#vU>G1|sF+e+ zcCu&WC&A7cHRPkK+h}UPmD(5B@x{YV|DxVZ2#c2L-SKr7GSI38o}VxHlIJ`9^$C#r z&fJ#t^KhDVEvU7f6s_*cA%q)VWC(#&9`T+j-}V7H9QqSvh6x@#Z(CEuuFPo3(|lZSRI(5(u^3z3@P@ zX0sQF3r8ZX#5byFd8(`QdWlEm}QXjo<vQHL z4*!|e_I8g!Y&p|q% z%soNNxLCWNIFJ~h_b9Qz`-YCw{B;-*_dYTj-B##hZ|2~WCVr-0Tbtb_7U~qa+Tfn9 z$Y<11V>c4)8qkn{h;TMn8SM&a6Tf^k2c{BZXkEaHrt)adgon2(Xoi8c$TT$AKZ5g#rL>1m~ zO%vsHZ*sPem5=)6bPg{QKmL@N`Mj=@S%2FcCIvxEK1vwJ4(3Vtq*Bq%wVNHpSyDbo zFlSi}wL5%!_tlM0D;ixTHv{;MP}Q==+vwDw`0T$pC_rR$u2=JNHw%=Ok1ndYbZ~B% zBtKHQ<~>u&urSQOkA6L)mvvt5;YbV=1+bzXfFfHW%tbo#-2joBa0=p#UOsc zi%jN9TQde!uVa(}&xvG$&m42EvCr88wvMR;lp@yJTK&U^G49@&6d6sa`0SZW7}!@T z0+2$4QRz*5I$u15Jobb%t6q|e`JGtM`F@hFZG4IHWw2T-YyT#9OikX7Z^i2 zUaTs_3uME_vN2D1V&mf2pbfi8SXXA~9~$K50Ct!Dg)yyngoXJ6Uqw#UTLwpQv~!Fl zk0Fq<3W({*T)f1!L|Bnbi*Wqen9I|`BvLPu9iAAzvO<}QeE+!h$=EEnv^>31aoRwd z-yDxpR*ICW${;(Ip+jLNe`LBCKMkw#f(1)98EvNBMufwETtS-Vk1v~#9}YDEs~*)x zoRjv*rcuD@gI1hwfR{AOxUZo;4?TSp!%+AHh4=*gH37-ay?sja_j=NdRHsnzQ}@>< zuPwnvL_e8OSnZ#>dfME#^8ocLiH zn%xw0v3QNaStXJ7f}i@G--YvZz5)QKhE+sS5TB(!_4;YGup*bg$ae1|WKhaoAC!y= zR+RH!<)8MJ81+H{z8xBviOVp8Z!J``5VBD5I75V+)i<4ib&s)T{#M3u#}zk+FX4RF z8WfjGi*$_eS&UA|x(8;o3Nj;QYaKf+Z*Qc%UaTSmncv2X3WocHWgsQO=mUNVrrlOB zCS*m^m;qD)@iNg-VbKbo9u#3LRJYa;cm&IG6xO*EJDpR&Dp7?ePRrSCxao$fr%V1;)>kW3z4D ztEV}HFRY6pvOb7hBKA+--Hz`0qUW!+g88CEr@j!y6_dSB&HD#uVg!Z=(tI@EOYz7j zl4#UMAHU*UWxf%|eF?xcY%u?ZZk;s`3%4@0{*`JocK(xPsO|n1IdN0x`7xF1(9ST- zt&#{I#h@nuUI>mHSwx(H-ckZ%-sg2LW6WSrcARnQWGroonD~nT;nQ6Y>{tvzUD)WC zMkojXPcV+B<`@3RQv9L_L7V49i$0|5b7Khp~;TV-$3EU-E*sC)m;z zvZtHO{Ns6aOUK#F?Y8G>srQlGEM6fB;BjW{UTi#0SA60+eFC*~{tADKW&d1lYP^#c zbyZt8Dw&u$4+Cldad9#Y#^kUAQ*Hn#gf{7Os2Ih>!gTmUywX}ixD3YY3tL>L*VA4DEk&zj`_}r!*-Vpz zX#iu#+DLM+k?%G2V|;eS&=3H2l+Z9~#6HN=F}(D`vh$7R*f{S>s8NrP;l~Agb9FC< zCFUE%>b7$Xo$g^ZWMz!|nLOSV=?rbjZyk&J$UyhE;j3;gec13;pSE2Vb^2vU@f3X4 znYB4BUn{L)nXfZXk4{MkZ=9{s5LAgRDA{U$A8JMPLPwr10J8a@iGMZ` z#ljd&u~&T^^)HDYG54?8yvL~~pZNg;*o;+m9VCMSHXA++r6DCYmyL!Ztujbn z=1|7?x?$>O`e8bNI7e5jBn45H8wg)Wfy9c9o|8N=rjp1!S+qvUNn>(X$^Y1Qh3dH- zO^HtLYC4X8`fbWU-dY0&U23o$k~UZ{EkbMKC7tfT?3*sEXhM1D8oYf zYO)u9yNlkj(cm60I+(zK&&$zbLqNap&alhpTji9>@-Ati+?~p}H-f+LWs!i$%amX( zt-Rn-TMZh?Mdua4?)4FLj^i(AIugV6Zsv(KnF8RmX?Z`&#ms51GCq))%XZUzGhWV1 zO`{BR#V_|j1Vj-eeb)G?B(c)f`aH0sco&94P9#K5#xuUKY|dJNtRJSR@hie+OHwd+Zl(lDQ`I)q!AUq^+d`&tvMWjGP3&H>TEKj7jmP1-fO`Z zL))O~h4-QTfRtjbG(_ab~mWHK54 z$j~=n31<=MipWDtxc;;dhG#bh9fVS1qtZ?Nv(++W=$-&!)B~^NoR(n2);Qwb!?_qb z1-nB{UV~2%=zMQDe2xR{%8tYGt;EQEuFXH)(Yqh1o?VguI-Yi+aUWp$wmp3l+cL+W zsU_roHrte$2NT+eQYC!LZ*sZzE-ll~G%8q*hvK#*JywDkj~vV&5~;v)xfp{)?f>+govT_0QIZ zNgD*rX7=wz&>~#@8-Yu;#?G;Iswr8hO)L?1&)r&*iVW>}Aw9H-y?aTC(lhf_t6GOA zobr;%OLAW*NA)_~p6%Tacf-dc$2Ze8&7coW;h(ljPjIZ0@VL0z;b$^QJb3zSkaJCwe_>a)*>FF)|jw@zLK zVw!v|??}Oq6W4i=65h>ZwOa>I3Nf)$KrH5*0iP2#$XBF<`HswSX#{cgom_2}f`6G$=-aiRgjlvNj^^Q1T2HUe{lkD%`W+LU4`Xz=q>)i z@!pI3ypZQvD!Y{l5J{;dfZcNO9C=5t(T`F7YnAphIBz?Vhli~^JDP8;@meeV%02`D zwVoiSr2_@O$V8H$|>bEd@aRxqqT5q43cj^buk+3U1}9wqp^lbI|wtyftB?^0C{;G%#dw$@S~> z2U~htOIw-(b9nbc8=cH1;_iZUK|I@|4%U)RL8r|bZ?Z4UQ(ISt!34_vvM1FB-ivUb z8aJy=H}-ZB)SqrpzDW*Ugb)h`HE98K=c{=T8f+I}gO7H)I zR6zX+$w}At8Jm0Ff*Ov0@44kR{2T6zdSiSK7uH1z+0b3&#+mXtKw_7Y&$S@lz4|Iig(WVRC6KJv;Z<`BiW>O*nzDT*YdT(#+At*a3$o!Pi2S-I zsDc*eO{gJT-z6B4GN)?{8s9VM3!kOym+H;5$8kIgRDR&9z`G4FI{@HC_L043vH`YW z!(u04DvD7L$ai#zU`~LQ^kNpDm?p=WH?b?m=^il_jt2UuV}HKCk*e;%Vt+bhR>;&x zSzpONWl-;*ECYI{5_o$?Nv%>iysqV^w?3~bvY-U=V1nL~_qL~VAw5Hp*@(xn#{3mm zx(S)Bk6O@0GDg4taLRl?ZU)6B=+oO>6SHo2&oe5H>I%s6g`xUl?s1AY1Ls(_$wBD$ z)h7c{#EkkT)~|Jet-qs9YzNlb!tme5((dUHEoL+|D%Vk+ExmTk0e~fTF)SaWSEG-N z!>3m7V+9OVo4Inf-&FQmm9*#G5R2)*=k$o0jpK5FoW3n1+vcp>5+;y6M(D~`@;BRj zzB>|UEO<@t-NT?;xRt)fT$s>&`B^cKr*E6O@aNf)>e>y@x4_+3=NKhD_<%PQ%Z)yg z-9p%{_qJ~%%kh=xc(W@gf`e4t&htj`{lzhk#gWhJv@2q|rZ9h0&i;IzpCD>r%TBXA z=#^zz!qz1qH8{owhq6BFlW!&jSo5W&fFwh1``rU6B8NeBv-MlA?>4Z<5cZ?DURS6h zy7wlZ=we&hU;S{g&2mLy1WlxB^efEh#?%!b_lEAP&_22<90(IE*n1EVzZt$x-(MHr zaZ>PTxfdzb`snWcFoGhQHE!b#>8>!XcX1g1R^3x!dIuKX=RnzeS1*ed9TgyO<+gS=jc|VfoV;r{LjnW<=lwlCxtVeIR2}hw3-FP^9 zt@r>t3UqeuD`qR&vZ}ch4}O}vuiX5&MgC~4F2@lDicYb^uYmt0?v!}=^Pz$lr- zbrtw~Hw2I##C)=FhyESNH!K&=Gd`QuHntbPI_CcxdR2u9xSs#rP5ZAr+W%vZ^jeqr z+swGyQjMt2&5h~s2hRku9LwT1sAB)qpvmKcK9*~|;hM}uAkWn=Q~FylBB$#G`PUNj z*e)qBSNyHuO%F>``Bl!*X1j*lU^-#W8g((!BxFsSUg%%8S(|zFsID4tZME(T09?f$ z$KOVJjIDA3Ykipq6<$XAEK74*HGz7FWSV>gG(wwsvNWnm;tdfmANPeW6FH61PF26YF80kz$u!U9+VSV0P@&*8?7J1?2-npMNylJ{E#GTm@36Zb&y7YbjE~`yU zhET$rekpk%gY-@L>0})#FLBN^Ouo1@Tp4bWO!( zpAfBum)Ikx>OlQuwOYPi(6UKuP&X9e%^{)NM5R(BrllWr;JMM{84t*oMY;#3TXviT zh$vz6XRc#oqtcrI4$99V{ZW)1?{t-PW#O5m5s`H>G#=~NO!`YNHbVWvirURe;wfDU zd!8!`eFrE;(i{g8v&->MM8zvGHD{=5b4d-SF)AF(QmBi}Nn^ZiOVy+$4lqiWIy5b{ z$Di{3UQfyAJ=FmKQ;2eC=<*-nEnDBt)aY?Nr?A&k=R1uwEfPokUG;?%{Z)@|d6<`D zU7mP$?DKvuKO8*|NiM4MGVJWhipmWOBCXz5#gOpB!T z?9p@?ZQjP_X7Iwbq{652qitJKLjy}g1J?3WdYTEy`$T9jXtCp&T$p%Vgbi zOWh?e6gX@ZDw?QoNcrt?YgL67dB^Xu^86OPo(*i)vvm=_8*tFqz*8ZZnDq!a?{4J7 zty9Ra?cO+MrjT~T3VNem)nhY_i-!R0DH}ExwSk9u${jWuc7_J{6%jN%#}fLU5K*^@ zorfb4ffLT@8fPh1oGvQsU3Sk6Cp{$xyOi&* zHl6XyR!|mE{b-8ky6+)qMW$0ZX5NC$av_*%{u<&;m<*Otr8y35QSzC%uj?bc?@&51rwU!gA+wb75XTuOFS?B4ce z_(Z#I$F%1O9Ta@803H-q&(0SnR%J5xmt=L;rOoUlm*0TmB)FF0MDN;_-0Mp9!1hn; zZY6&|-TG&NZvk-`awsj#Tg@%;?J<@5uz-gnT7%jjV?jf45P;CITfEN}Mc}d4ie^F? z8GGmbtZi`uMa;=@4)`r= zTxR)5V^jn)Ppp*8rIgUG+1nAz>z}UBU zH>Jt5iOao7Ma=VvfeD;VN6Erz$`fr!t0|DT%@}XbW^_L0Bh8EkW4Ninda|dSQXQ*i zJiY)YP1F>RlE!C~!>ufsqG*U}_fT42x*7qzvlb?$k`GUsq8BxE$AO0$q0>E{`(i~L zt)fcXoP}QJ(rtt>o{XH`m-K#DtB5JD_muKhw-{50Xu@bse=c@N#Lmr&fwB+o-eH6UI`=0X!80F>rdWmo!=Ay zhP**(jqvrvwCdqGNlacruI6D@4uu%JZ7Irr3md6}MdHp~=Bsi#8=>J1>aFvmXYLO- zxYUb9&#W*92nH|kH`N|Ia!f%c$kE(t8CP*nl9F=M3Y}*YpL7oC@~W?5GQoFBe!;2n zYR7er9ZmFk-ZfrvpC@^jUz-kazVD6lE__UE%!n@M={R(ad}+gP>FEaJ9z_jOdrq}W zm{tI$dbi`K!@Za`ZkNamg#C{U3$LfH%)fuLt?NH`)IO%P8{64dev8`{J^(2dwz=fA z^mh*;Q_zY_WDU|vUj#2Qt|e)}kbR*YUD;Hvqu{IWa!iWCpzbI@z@$hY9Ffa}nYvCY zqRoohjJUm90RXTVzP~kq-Iqd-Fj$b;DT%)E_rO?YPz;+_V$gwwnSvSykkQPq^j=Ag zdkpon7H8mQ3|SO)(K!oS52=(0Ylcj;sc1qS*no-uS+Xfri}KCF0&15H5-=(_wZ&WN zRS&ar%>g>YY% z`a&WSOI_|Kzt3=^lHH@MBx~pZA-#MPl8gfW&<=E!??v1Qkh-2|0En%y>uEExeA+cJ z*cp?y54o@SV&X)p1ZQcJWi7`5 za<$O9aEv~Ey7u2kpQyY!{2=COh|mH-X!|FCPIObW{M?g{`OFvldNG8K;3i8Ct!ofu89Ps{MtD|i+#x1cX;gr5{2i<);x=Udtp zJum+v-u%YJCmWb3IXU}tb&Yz`|jaO-V z_#L0@n=cn92fo*kTRmUT`!GG|8cyEQ*H;S95vr>Oo>eYt;A5;MN{OPP&k!j5E7(} zp#c^eWLv&Y!yiZe^d=_*{5nY&mGw}<*_H<-(Z2aX7?{Fzbuk&i@OeO`aYBj-zrX!! z9&(yDmM#OH0y_S#48F=5NS;T=GUK6mazNn!tfBR}%}V8QU`ro`d}XAmV(6eXAmEsz zolplIAj+ta<>U0{3_bPRT_e;ba=~G8C$v98_{Ta<4_9X-o&mU?|E;|GVTTI>QVvwMa z4zuj%VRCV&aE`=ot?hXlq2P(t#(bEa$M4 zWA|}ptoPZn6dIGIFtinUxfl!IGbKgMZ7|UM*GY0^3yYyPKLrS>dS;k>hpr$ITVv}= z{wVfA=NIgp$a7B7BWSejmqX#UT<0G;`58tUd4RO`lZ5t5iH%H+_XP!%kQbO8)ZNWMr= z)J)zrL@1@ncQ+X@}uq5l}LoN|sYm^dxMNm({^;Ss?6QTH%mN=OGneK{x=it@<=QjIeg)XRA_Jfj8j4kHQ2`x z#gJRbC|5-U_Fs%b<%e{B9>z#eFk`HOQi&yB!)bp?_3X8BEd}1ld`C{W>K*UpbAMWR zbpz)z?>lCGMA4cetX622XTLQbEYR(VtI)q#)wi`o={3D~74T7r3_1eZF%n z21~x3hLD}4*n%cc9@)moy@ z#S6cV7Ic1ds_;%~p615jBIq@y?Y-U$=Kw&svlfa}om15X8U}l8t_t6_mb$xZ1Bb3N zE~d!2#=?f+O>*~=}F)}8@ zb8~XTYC_%GGDI;s?&kTl)H4gslNk8y>!pp&#v1BsDKOmKQ3#NZ*7)+3g;-|9I zUP`6|rpLT-+EeZYMuA0_)FxzIPu8GeDeg+#)ipPAYE{yhL*TkZywa4rPSgs3wT91C1u@LK0_eoQ?qZ6 ztc+Wr*c(c4FG*{6X}Auhan;8@TmNk#@k;>N&g4^fhXS24&9zU|FG=#%SD+Zw?vw9X zZ`ZGjjjQn)lZ3Q`IpRT&Evak=v~_@{3G0UiGFZk zrjmMlw<^_^=^fqPi+s(GR6U32UCNXxV}@ z-R2X~UN_1r!s!G=Kk1Y-HO)DqFbdJi?Tk`oQWBpLWp$R}j>PB48{LFCNlvQn<+TxQ z0^5jb?>IL2=!4d=h&>~Vt>c>ImS&dXd~hIl9t$kF(&}t+$%4r$!j}t3 zs?Vv^AECh;H|HCFhPXu-=k;vrKDBw}qQr6_^k|ITg=QiFgl=wi;~QzbS`$@MP@k+q zm7pFxmtFt{#;3Iu9ENPrfZ2mzix^$)tS8V3fHppjKC3IVPk?~!mqocc+lxs8eMm)8 zEV1`blT2tL3aXd|FPWA+JWnZjB)Y@SxkZQhi@lCnY;BNemuKk_8yaHeIHVVJxt8}Y zUK;I_w~rxY!fp(D3B0_9;oCF-m7*A{s({f;pB_FTY zvVUzFPdPo#A2kx%M>bdZT9=Dy!izcnQhAGh`)+j{TZC}bsHcEV{S@tSpCgVZo<&ax zQp>Dw1-k}`NzN;kE~4Y1!&)_F3dZ*-?7mEvnHhrDgVrsi6S7SS&MSLO%={7+%`5S4 zsi^EC*723geIaX%<<;5!FL!u+K8VoJ21eIThQbgxrwF{R-O~jg2#6qsa#}D2(G0K0 zm35Mud%1M=kzsl1?hOl#&ASV$-*5TDUrBTt*%zOkc^lWe;86yZr~382UV6xS&hq~C zanC>u&%K~&!Y}e2$2|9(Ds>CQJAXjFg|?9N{w&z&g2cj#Cr`+M=y4a2oJ@h?A6&)% zy(`b_f6(%6lg$a+mcaV)A*AOli-9E$)pNnf?r#Zt%SS_{u%`*hxEzrRMl9cgppQuU zRdrv8Z-$u=lhZ6y#`k+(pS24~XG{MT^*?LTjA-Cp-xe6>$Ps+I5aaw&FS^cdKIF!`UwDcK-*V)BTc!F=QmjhC+AX3?{RluZ4l@0#8J;XhP6-9jx+$GePg^ zBJT@h%)~6T<_r+3GV99IIys5L5zo3f;dI_@lqD7lcL{(e_r;CK?Aq&=1?Xvz6hN&t zm>;K_iHj9;xuO+)m0=L3gJ6+YaT`nn`~!a2$eSSejchsPjB3-sfVEp|OqmlH!-k-| zjDLY5IbiF8H?BWJYCDkz=^wq_g3=C(>t8xAc=dk`kN8gr#=p5q=&k=N0g@Wa!rAwq z0T7P1cm}Up%#c0(7A5V%d+bSst#2ZdSTD}mNk2BS?jWO_J%38PfP%oorcp`z?&G}w zzlO@cHSfO?T=_pTFn{V*g>Tk|(@b_tkB;^#GJBXgS;-^72`v!+>DGhWX~UGqv6`#@ zod~b;KY1;ddWBTTVXu+GW_U(rIkqScUMuYdB;e5j9)T^GBcp0yrC)9YBAYboyA3Pv zU(cqy@42SpsAJ@;Xvyw(orr+tG^-C>oLCln-!8#GzuBqm?>^Yn=^BJqrwK6(P^tPKPKyxq*qUGwK zQ{pu%T7F=C(if%`jQm67(j$Ktpa?|z2z@+BeD|jhT=WzPlY^P7-0y2no|3qn-z;qM zHvDaEjYIPC2pRDI2>wV_PVvt#5co;=H@5rPb2My-(Q=pnqM7{JJ{~Q{tSzCSSpp{nE+61_6^yn;cFq62&>9mVyPsd z`96GijR?pt`aJ$mEP%Izv%%mupTRSPzQE^~@Vik&?KFLO#aP@c-yc%Fz4}plgOTvL zk#rZC?-YgE@2S!$AX>gHm_1< zo#FHa_^lw6j@8HUV*?2QK*A%fVBOUNm_nN<-un3z1{@C(KHTpiRDJd>d9^2U5Q0Ss!wUB*2Nq8Z>Aegl6bSy-^{|^cl8PKpa6IkkW9xt4!^cbAP zEUIJKDQe}%qNxntY@a+ zH}y~V(3fDC$gk$*w6>pH69;_gyl&&VuA1`tk(bzP)FqnDOKYpslE8eA3neUlCPNwIC=_$(LJByK=Sm11A;&5az2{9_P<30g z!?!snkLix1)i!TZ(I(F%>V$gKE_*Tg=ER;IDrGC@tY`ezbSFGj7Dvi zyCk#|ay_91N8f#Hua~2GChAtmX^9E2{Z|w5& zr9AT|)@q~AQ<-w{r}OZ1E2~~fsHC-rB#q31-jY(V6CB&^^ozM{4>e?BEo{q+ zaNu%DiA6AB<#Mj>pcD&nyh%w~w^j5exW9MvQ#_&E>oL)E2|=LcC$RF|Nha3)L9T z!u$2Gp8R>!bv(M-!NXWDD^SX;(o`bC%mq5=MKx)7eSH0q66%yIHN(@%e1Tu4V~tva zd3p^&J@ZrWn~$*j+rhBX?#jNH>8Cd-ZeBjRJ{1)k%mMfK_ou#qIftb8FVT8j&AaG} z0^Y->U<1MF4K0Q2>L4bI;^Q%A#mo|I$46O`7vHfq?ev;a`F5A#)(mABzY(L*+S;Z! zPlXc%P{DSOsg+s3?L<@RYb|U>9qW6&DJA6?LCa=5m(zXVpH-krNjS7V{SY1G<_A^j zS_G&Z-<@7x>i(7UgT;(5KteTj(-WGOjkI%?QLp%xsnB_C$ZoFw@NcYfB{n0z}n|-4%ma$DEwCc7Sf!r zR&1On2rd)y24|g1sguMxXSM?*^@@XfpVz)keV>nOVcSDaFUHqB7f>+5zJTV;SyztH zE4R5FUiuw>Z7(?K5-0JDNjxhaZ(b!hIY4U0Fo79N5S_`5I!`OOXRZQEDwtmCwBkUv zFZ+UpO33A6QsC?Ll#&jLoW7O$!zh^MVOb#x!m~{)h1mQ9El28pDkv-E9Tc!!;WCAv zn1dl5R7Ws*p@rKmVmM%yPtFGUS;^NWm6!^>r@6^3AO7F$iLcQV0jBZ{!Y&l0<4H3Z z(zvoEl+>Kxq;ZAa#n$rnD3iEa#P`aCPFj4PbEh6uf5T*C#jEzdAGAQ2l7-_iuGX_2 zIz<~xw$&1mD##2{2rPeMk(PDn%Mncdb?pw7g!=TBdIzDHNCqKtZt(u_mHE+O85|Cb z`iEI~9a0j2D*Yuuwy-YTUhzz}*@mCp;?HI#l%`L^5}n*qLbd{V!4xtv!b^tdr^x|9 zD~dZzdQ-E@n4<F*XKAW{vR6GbW>;7z62WC1ufjljLxroYMxe&4 z59az&&l$o|ol5yVOzk>P*?irhvq4jYN!E+hH63M|v8VjrO`BG&yNz=-+Q>1&T|nB= zd*aty@7wbcwaa~W+Ji}u)G7RZ)k3+BW`?K!b;llZs>AdT{wwrISGZMu&wo|TiB;6*4!jX#kV@HJ_1BSUD9>6iOJ|KeR+S2C~)6Qz(8Q z``h~Ud_Sex2wpfqza&~8JQ2Vte7sA&LE)!M!lI>B1qfZVe9S}%Z?80v%xOH6j}Mtl ztx_Hw!3F@(eNNjA|Jo>lK=$isk(f?YfFE_-Ka`Am-Cs(kWXTmu%DHc4L~?sRZzaO( zsragj--Huskuz$Y%cuHG!?qL6M}SECI{mRFYsDewYCS7#qB5j8(NW68fcC**%7C>=yUB53;La^Wo1V{#VcMD{2ncxn=-Q7b7Zo%DMC%8j`ySofJxDGnN zz@0qr``vTTIp3-8+*7yiuCAJ{o~hk?@7}Y!d;Qjbt#x9>vPO?{xJ9|!@m&641zmGx zyL~yopcH{0Vd)d=_Zl-hRtlLa>fsAM`wIB#HCE8VC@AAqBxTVhw^=?jG{*a} zHC!ayr2yp_>?gb#8d;U&oNkitRjJ8z&ijLUwRx^|$N9dOhQj)B7afmgCy>ot+G~+- zer9fe7PfZFV-Gz;b(OV05ESFnvV5X8r0yK}qCke$gw||>&m(YisTZvcQ}^nHMd|dg(Q4?8BbsZB|=4J zg8e)2-(3Zo5$n|oG6iwjV{DJGtZe9U_>%9lrpg zMCd;{4QaUM!k`)xDzsrhMjTDxdMT}&nnQ(n)a#pE*a#)zEAf1DU5EEHE+_u`kY`2!W)6TE(H&H+4(M0hwpf;fp$qi=}Kdr7Is!**z^Im;_%Vq&B@Y|A1MHN2tnvlo5kv}{GF@a;7-lm-@_a$bY1i_ zqunGCCRz3FY)0pj(hECs3ueHv3A^ayA{T>_Q}@C>OPh>l9Z3R)WDGdLweCrXen*me z@l2SQ&sAU;X}G&`=7@|ItrhJ6A475fFcB_Jj5w?6b4{Y}qDedK);e+_MGTU;bO%Jr z4i$G{aPQ1d%gPVyacVS2I;8O(G)zTGpt3lbiu~5i!lfs#h&*!YqkkadjfM$ip%J8B zc(5ll%LEftrH93#d5gdMW6Zhw0brQHMW4u%Uc&obe7Hs9U?RK8bGhmWad=E?Rb;t- zIAdX*zN9@h!}3D-K`h%zo#w#hyyAfC$T3UuM@O!1OG|?$m{;oQEo=HS7xegcau$*! z`O@Q9X7K{qT-(6F6|L&N#hzdbb+&8Kj-rd=0Lp9u>5vCOyBQ+ZF|62PZKamu*ar2X z?Lan60aJ0H5^AB_o2km|3o~t>s(Ogxlxow;_rtPxzgB#II?xlqdmT2cXSC zk#RV}QaH5vw@enkJ*j^3%=oij;z$aUkV~n-oT-^^=5!)rq%>{B=IJRBXY{a6Ax3J` zhwfO;<`db?*?i+2*n-z)QR^gwcfcD?CxtJU4q9qLyp#INe10BbAEU=0RmK*?Bo|{3 zmTG(CY#}Qh?!JbudYK<>E+;F*5t7)dHKTeIL8UcnV@vmObSKumx8iAXAjzQXEiJ3M zL3Hh;b`rleO1s;Rc-0ddXbT3+57#d;_oI!~%NLR4L}b%oYbKw^>|bY_-{*%(y^e>k z%w|Llgg1C()sDH76^=DUd|;Dy!_%=)jTjMIT72mnDhp_oU?M?aDp+)xgF=jdpSz=B z?^JVYy_+h|tj{dGe2C+tC@IESxLRQbemCIrWQ4j{p(w7(vGAJ+r<@E$xsgipX#|SPd7kPvjwm zaQb-=!+%_Wug39-vOa*=OyGm@?;+0aQ>A0ogB*`oh%WuF*yWiGaIZMp*9&M9&-63= zvS-=+%rlp@UCK_FqheisIPIA1vzmYV>_3eT1v}yD9v439wC&C8Me<%(DMkxy>)eB6 z3?ftD`n-T;nzG=&6%tu)Z#B;vu(eNY*P(jyYCH3S$yd)SgMM=%w~Ub8WoZTrDj|l# zk1MS@%?BL?bEHx-D)jNTcg0)Csmc7uU<7}_s80rOs=PQxC5LY41KR%DD_ zmowi+CnnMBq%^xajwZ#d)r3J!>LzUV{n%6(L9AI;441Pbmc89bL0*CnyEh_pcF}J{ zpUdZFdk+XKm+UXMIT<6?^3mi480vPZ`&g4*Z`+R%02LNbuSNXKvSUMZUbeS*i2m6v zY17FI&BV~WJxjG$PYgK{IyzVFET((1QuwCn`6%SnA%8Zs-{^ij<8V^^?C~NkoksbZ zOwjjyxWUWlK_=#-O|Sw^ZH`QEh}^r#WGb*R8Hdge!%hB!C%reKa0a1E6YaBEK$lff(*}FH!vWpo+Bod_+(r{u_PE=W zHAY-cnF7nG$f~N@iM~wJpI16KcialX2Fx%n^haeNY!dUaL{BQ;i@4rWW???PliLz_ zJmvABP$RuHMW%-JNs7YUOJt*RQU6jvr1O*}!prrBvBR|{#6>vfoKPsRuphNPQy;3x~HlTQ2ZT8{(=n3jOj^!C(!OW~K=MPnl*?mPaR4UQ}i zUfGe%nL}uOE@&>ohC)U^?o5uB=6aQbGK%hCQY=Lmya3Yt{cxckEoWe z3Mh~DukWEK=2F9UJIogRCC8eh?vQ0jPgCMk8ill0!RCj+SI&GzD=no5N-!lo-y^n9 z%HO7*e~H^ZpJNj;Qld6{zTF6)EoQrl+K4K2 zt<0%fk64m5&cEnTC_>euy-`rVw`k_|YIt4Ly5VE~Ud%I#lNoxl=HK*D zsin_G@WV(!#^o6CN%m87#{S_aDB1olHYK44+)Y(+PRI(7J65vVpx@t7JNdopFMEiN zNPB#$+HZ1QuB^QzpP*c^8Hc!-heQsy79OEQmNqS${cS?59m$F6%Ibpo;-u8nVoSrM zM42RjsX@SM`mNP!`!Kc$D<7XToIODhqrpU`V7fA6rmJhQfyJc<=8rNm7ZNk0URmrT z@F~yo*RT$C!hJ<_mTAe?eaX;;976R0yzVc*gWGL~s{RJVi$KLHU*Ta%h-|it18+D0G*NPkYtC6$Qn; zU+1>K`9zSN^ftUDDe;SFW!;A)-xXWcJL#9q*;hg&oWkZPe17SRY1aXjANm;en5(#Z z7+T_EO6OhmUPt>g`v_^d)VLwv1W{Digq_T1Zz^yyTB4<)B;{gkR!BRdy+{50SFYJ7 z9d;96d774O3@v>($%i}b-pwos@h3EJK2)v6eC5hd@D)4-7eQx|k%4#x$1SC-k{7f6 z%Xtw4z?D|rr1q9C*0!k@d^iajvds8tZo0R&xweq7sjPW{_uqol!065~wlQFO`+^7m zdiB)OPBE?eh=&Ka+q+c@xMQ>H2;_;V)8#9ZZSVcJm_`Bg)jSz!tg90rcS>Q&zG>~QkUq8N?{of#qPiS{t>N~sPL zrLQ}E?|MboAC#Ij;4ca6)i)ABd6|d z!N-FicdVQ9vB*)Val^l?Ihb_gh+?X8!$-N=+~Q^z_E;!O^&E5a*@}<<(&5YL!;iS3 zKyE#~N?$){R$O7Brxr-ka=2Zk)w?`CTp;c`R@mIW#d;ZN8SXzI_U^7vbl#RzPW*f` zL&NH7=C8ih*=-|$yA3q2r0i|qAUdmx92GkoPE6)WOhL?%a-~IAz8dd9N@n6{0KOod z?$$gAI#$XE4Q>#cRbC!01|a4q+*f5-7+Rarkpe1`;G^mTvdj_SK#Te!L!@YlTMyUl zXzF{+**5`&wk1_G+3%`PgX;^Y(4T~5;kl)yp6+xOfxSf5i|zez2;aqt=p=f}nP(@L zR)>85B*SADshp>RZ7(8oJzA5J$l*5@)9MxEQAvUmEC&)h*>+CMVqM%qP$U9}Uk6twZSAc3{psi9G%D|%nk%Egb-KM&zl9QM z{rbkNn=6}S{^#i}9GSD?kd%;9Hu{Sx^X9Vm)2H{(p57x`6C48vm)t&m`sVlPTQrHJ zH*7{qN4zatvDC+CyQeV=5_41Y zfiU#-YO=`*2>o)p5iTj8wx(V#V$4`QBsqm2TDTILV!fMhku%!7B~;(c2oy#HygE^E z+_t0d;7Ke>8sYtQnnE6RHigVCR=H2cduEjJ^&|Zx)9YP9cL;2L-5-*HPY(`(-c90B zV_Y3nD!E{5$N#~Larf5!s@@SQYl!Nm&Kl9`^t+pBM)H@q?$Iuw_u{P)m%yLlGFQAmf_!sM^$)9Kg8F=J7$4C_%GP`m{}Achz@;@LA!y*WI;JY>ChW59e&5i5+ zzIw+QZ7=&0NQaQ~J^Hd(fy0_%u$XGJLbUOk?OFA&%n1kE#%fc~H6gKJ_bp z;4n5ttE$P4;Zf)k!TkNF(xat#8sI028sbUIjBZHk9>E`#V@1dPuGab#2P>PIk%q#@ zq()ZLEz?3Ht0k{AECYp>73jUgehvu}*m|zu#PNaGSwe?fAWiO z;I^8&plADqmQ>dMk+Am!OgaG3T!x=<-)lW6r_V<{KBrr778L?E7f2W}1(ys=SnD)? z0$yyVQO5iPiW&93!GUfs^3a+WlI0Ay62gOB$r(?Hx!6>+ORRp*JO_oq=m(b-Z4#Tr z$H_T{TJD;hfI!O4R_~SF+R^tV|}7 zl&p+A-d?H*L}sgyoRrM~h{b`LQTsAU_~h_pK}a{#`E4Y`pm1EVS=hMZLH9bEJ ziv15?fQaND8{@zX_-^5sk9<|P({422rX@E?3oeR=6!cihQtdYcd)TDvJx3Eq?#f2@ zhK7ebhTVOVkwwZo&7_gx5wgq&^vxy;2!Jk^S>MN%i4{CrgWg={%pZ>xk$3%Xe|=c7 zo;}IjsnEx(kt<3`b1+1P0Cf8^u`y*8KqquOldQr_uW0sQGpEyFwz94$DGQ} zVWL4fI}(MbJhHcis+fT3y6nnDfn4OQ*UD~ z@8}BX$Yb(R^C~$|RKvuxW2-|b~}u$u11b^*lLk8i(74FPVpuWXB=1v}r8#>C%9oaW{hlcIulXK(h@ zyQwluQazU}9XZKu7T@4xlumaRCKAFW}(9_dVB?yFD|f} z)6Hh_B|2xLA0*o(NjS~}12pkq#&gGQbE#xgqm8J;w_qZAlZae4m%ERyQeuZ6coen? zuW@!N<7xO)P3#yJvbH+y|-~}?vmBa+n7eB3S_Ok+!q#9iqp%|B`s#t+*TP> z0K*l%NVH28T%2pqjfW@sN=}Rx0BUiYg(UlF${(J%I0xL6)SYn@fXJjQ3AwqQaEQ9Q z9;I5r25%Gzr`vUQ6A+jSAKkfiax7iru~AU@M3hKNZ=1>NGa2P9%=sAsfv}@?^C;gT)rn>CuyOS^-gk;_B9T-p=7c3i&_x?gzV8Vm zCY&W^AV=52d@`Yb9!y4zhIM+YfhwEjizJ27s0@RN;mQ~ayk2>t z(McSFKQ>>u88Hppg0j`TcK3r{GeHRPl_|3!AB4dpz|>* zykui}zedVS?+TxF*1fzt7q1yG=cbC@qi4}au)1eFe4pqK2LjWTHg$y9*;f0tRcv(` zgbB@fBAwX$az0T43==X`(j)o-$sURm(#jA`XudPUof#&1$k&ou7EY(Y89Tz#T$NuB zt5_R)g*3Xv1-|Cqrf0Af64C`*vO|}Z9y=v;mhFeLsr^G~WhbW$?Gn<*;hT+(m?^(h zEWPEX$FaoY^u^GR)p}!0&6U=hGj$0`Nf#S?B&tfgx!QAfxHxT1_IAbN0BVHBW5E&j{f&C-Q zxjy=ZJ0yMugQl4ySZd3jrv&Z!R0 zjA>iHd3j~tmw0z}jjWmg0ky}*l> z-eH?!*_7ZnWgc}(E#fOWz1(RWAFVv5e?0HGaoN*;*2=GRtJ1;N;6-htm(8H}z1e;J z1$)|w?jhLeDtyHQP-?y0r5O-`VmT?;JDkxLa7XK$1(vT|1~bA+7!r$yyt}*;y6ILj zU7frZN94=4G)6~cRm(+G+QWjx$IbSkx(H6v<+hcrUO8R(c%}Wuc$HyfQd)Rf5{cRD z-Y_)WKZP9|TGrZJrUBR-oev=p8y>v?{Y+GM{V3$1?|*X9y@GrtEIL`uYWKTNYKW_UkTmMU^n!NYye@j5nv{gBr8G ztWSB3L{I8v@Aojbin*Pk1WWM*waf@*x&=ds4tK1Acq@c9L}e58slDXEqQFuJ<4(DV z-)DuDP#aO8v+#sxX7QsZ^^Hy8D!p|7bKD0b1az)LPlS`5z{=?CK5c_8V|T5<8`3qA zBhT=-2eF!UJ@za(y%_1sB;Q{C6XRg-g0(xf0b9RU?$90@B%fP3d^3Ml#nC|$Uf#d} zw^(1FLv&!1yBqh^i&ToNHJrXFUbYpzn!&)|jfM^WN|w&ivy1{76^?3Hm%yK5UOK=i zN0LQFMW;JNE>A$BqMSxAGXxiYp&BIUE)PDKa*b?rKe<6ql{95memSQ3)^Y)NorKlY zqt# zOmclehWsx;>8$MY9o9^UZ)@r_y%@3NiI_%uzOA=N#oiHjbw^FmbR1;#l8q{e=oD8(CzhZ<=OKkZh_`Ny~a z(d!X_=qGxo^O#aGKGyEn-m|kOCJ>;vri_6-2jZ(QQPt{PPkHvo@c;?awy{rm;s7U6h;+Dao6pan*~w`Sx0_Nbj22 znQg+e{@4BL2AkEOd0G3n6kBSG_ zuclyErFLFzL9WL1V=ADzGBNHH9`#XJt}Zb^Qw|N8FZ#Sg z%@R(c_75JKp_sE_mlO|b^82*4#qB7*(J3keP{PtmZsesljBO|lDVE)>mOqdv)dbAC zNo??c1QddHLV<%%obZGr9i0HaV^J#$62gnRWV(uA<=>0LD{LU1lges<&;C_jm?)Ym zKhSva8%|D`V(36$-nOvz1KeDq{EpI3>yYvU3QwQ=6`Exoapq`f;Vs7ABcHZj#2y1% zSPRWMN!}h)T*(ygbF{_j!XE&;X7<+*KNdq7a+ful+iqxgIG8+01Z)(_R|i?^Wj~!3 zn^^UERRQxc(Veu3h_a>iy=i?s4cU8on6T8uC5*)K&tYPNfpmD zH`S7N@QJ7mkE-yOE@Tw+D=&eRhdOVUV@iGUb+Q^=oQB!Z@A*N7D-zw}m=iP_K)~#g zyf*nOGR#*E9<5@?V3Y8$%MLPvfV`q|?Pd+Tjt|~uD_0pa+rr!js4c|1lXKh3Q(=`R z<-&^BgNbPAJd{ZxyVQ1o_7mtLD4@21mK` zpk(@o3<0~fHZmX1@q!Z}85GVZgHP~`GSMS_6mVp9ejj$%k$W;lL}0!hC0#T|r92LAgoDt|a z(>{G(y(sdcQ-boj2DUL95Zvcla3%EmJXKc#<*-XRrkt|49I*og#1Q$tz zvY(8>>a6Cr9Gj5J+vI&vvISYq!V{F=WR%Z{egYR?UCK~BBjWU~`{JkE66H}T5Au>c zQx}{oG@Fw93xaUOEzPVd(1?hdAtC5GDDy#oc?PlkUFNV=8VN67l2pnZxAI*uJBc@C z+p5pi&nuQifw0?m$Oc}wjMXCzx?jyc2P>JI3)Mg4EZug@;^TBG=QeF%>xC$ya7spS zhj=*I?Lj;+IVyCIXx=rVSa>LN)Ey)vZSdFIh-`*_w(um`a;mGS{+DzVs#Qm=_+-y? zZ#`@GO;7Amem^{%Mc>+>nyX+YrVQmziiG#{ZCz?Z4#x}?scn9QMj>6foNG_$LhlFv zdz7$E9iwy*g+PdBEf!Xz{rR z2?OK_^DqH6UoK}9{<4?sCmiSXI%UW$s1(VZ{yCKL`?dYQcK<&mKmQH0blxz zXF?-(MzB8+|LbJms0*0soOE?sT;-XQWDAsn3`*N5%e0 z9847^A)#VW*c;?{{5~dTzW){^+ujfIHhelP1K^-7raz?$Io%U@WpsKhF7auu^%dhDNJQHAR+`H zVaqx?%30wc}ilb!Jf?f=u#EeR}W|ArN>T(QfPZ z<4>>SIn2-Kn|;wM-b$3XSS-<*)vG3h^~y~&?PN!_POzJV1#uuHu`r2%vv=6qa8*Cz z*mRwvV>o*ULGZX#O*1FaAr4uWmlYXeK8?cpJ+hFAdkXfcfy>LM z@Z}(B$a@uLyQAG2U;paQNm!4IODuGoSAIT;5_Oi+)mVRYO>HmWfIPcSLU75Z?zBQg z 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 2.0.0), this branch is merged back into `master`. + + +During the life-time of a major release line (1.0.1, 1.1.x, 1.2.x, 1.3.x, ..., 1.12.5) all deprecation removals are collected in this branch. +On every minor release (1.11.8 > 1.12.0) the `master` is rebased onto the `next-breaking` branch. + +Every time a change with depreations is merged into `master`, a follow up PR that removes the newly-introduced deprecation is created targeting the `next-breaking` branch. After the next minor is released and `master` was rebased into `next-breaking` all the PRs from the previous minor release line can be merged into the `next-breaking` branch. Deprecation removals for the - possibly - long running major release line can be collected this way without having a large number of deprecation removals PRs open. + ## API versioning The [API version]({{ sourcefile("src/backend/InvenTree/InvenTree/api_version.py") }}) needs to be bumped every time when the API is changed. @@ -144,7 +162,7 @@ The core software modules are targeting the following versions: | Python | {{ config.extra.min_python_version }} | Minimum required version | | Invoke | {{ config.extra.min_invoke_version }} | Minimum required version | | Django | {{ config.extra.django_version }} | Pinned version | -| Node | 20 | Only needed for frontend development | +| Node | 24 | Only needed for frontend development | Any other software dependencies are handled by the project package config. diff --git a/docs/docs/develop/devcontainer.md b/docs/docs/develop/devcontainer.md index a7d2f8e1f6..a1d9721943 100644 --- a/docs/docs/develop/devcontainer.md +++ b/docs/docs/develop/devcontainer.md @@ -60,7 +60,12 @@ If you only need a superuser, run the `superuser` task. It should prompt you for #### Run background workers -If you need to process your queue with background workers, run the `worker` task. This is a foreground task which will execute in the terminal. +If you need to process your queue with background workers, open a new terminal and run the `worker` task with `invoke worker`. This is a foreground task which will execute in the terminal. + +If you are developing functions that will be executed by background workers there are a two debugging options. + +- If the workers are started with the `worker` task you can add `print` or `logger` statements to the code and monitor the output in the terminal. +- All tasks can be forced to run in the foreground worker by uncommenting the `--sync` and `--noreload` arguments under the `InvenTree Server - 3rd party` entry in `.vscode/launch.json`. With this setting you should not start a separate background worker, instead you start the `InvenTree Server - 3rd party` from the `Run and Debug` side panel. All task will now run in one single process and you can set breakpoints, inspect variables and single step also tasks that normally are offloaded to background workers. It should be noted that with this setting the GUI will be unresponsive while tasks are executed. ### Running InvenTree diff --git a/docs/docs/faq.md b/docs/docs/faq.md index 3f3bbe01f3..7f2b2c79a0 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -195,3 +195,14 @@ This means that either: - The docker user does not have write permission to the specified directory In either case, ensure that the directory is available *on your local machine* and the user account has the required permissions. + + +## 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: + +{{ 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. diff --git a/docs/docs/hooks.py b/docs/docs/hooks.py index 2cd00cd586..b038738565 100644 --- a/docs/docs/hooks.py +++ b/docs/docs/hooks.py @@ -280,9 +280,27 @@ def on_post_build(*args, **kwargs): ignored_settings = { 'global': ['SERVER_RESTART_REQUIRED'], 'user': ['LAST_USED_PRINTING_MACHINES'], + 'config': [ + 'INVENTREE_DB_TCP_KEEPALIVES', + 'INVENTREE_DB_TCP_KEEPALIVES_IDLE', + 'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL', + 'INVENTREE_DB_TCP_KEEPALIVES_COUNT', + 'INVENTREE_DB_ISOLATION_SERIALIZABLE', + 'INVENTREE_DB_WAL_MODE', + 'INVENTREE_PLUGIN_DIR', + 'INVENTREE_DOCKER', + 'INVENTREE_FLAGS', + 'INVENTREE_REMOTE_LOGIN', + 'INVENTREE_REMOTE_LOGIN_HEADER', + 'TEST_TRANSLATIONS', + 'INVENTREE_FRONTEND_URL_BASE', + 'INVENTREE_FRONTEND_API_HOST', + 'INVENTREE_FRONTEND_SETTINGS', + 'INVENTREE_LOGOUT_REDIRECT_URL', + ], } - for group in ['global', 'user']: + for group in ['global', 'user', 'config']: expected = expected_settings.get(group, {}) observed = observed_settings.get(group, {}) ignored = ignored_settings.get(group, []) diff --git a/docs/docs/manufacturing/bom.md b/docs/docs/manufacturing/bom.md index 72f0aef389..7e82cb68a5 100644 --- a/docs/docs/manufacturing/bom.md +++ b/docs/docs/manufacturing/bom.md @@ -4,7 +4,7 @@ title: Bill of Materials ## Bill of Materials -A Bill of Materials (BOM) defines the list of component parts required to make an assembly, [create builds](./build.md) and allocate inventory. +A Bill of Materials (BOM) defines the list of component parts required to make an assembly, [create build orders](./build.md) and allocate inventory. A part which can be built from other sub components is called an *Assembly*. @@ -18,7 +18,8 @@ A BOM for a particular assembly is comprised of a number (zero or more) of BOM " | --- | --- | | Part | A reference to another *Part* object which is required to build this assembly | | Reference | Optional reference field to describe the BOM Line Item, e.g. part designator | -| Quantity | The quantity of *Part* required for the assembly | +| Raw Amount | The raw quantity of the part required for the assembly, which can be expressed in different units of measure, e.g. `2 cm`, `1/2 inch`, `200 kg`. | +| 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 | | Rounding Multiple | A value which indicates that the required quantity should be rounded up to the nearest multiple of this value. | @@ -27,6 +28,18 @@ A BOM for a particular assembly is comprised of a number (zero or more) of BOM " | Optional | A boolean field which indicates if this BOM Line Item is "optional" | | Note | Optional note field for additional information +### Units of Measure + +The `raw_amount` field allows the user to specify the required quantity of a particular part in different [units of measure](../concepts/units.md). The units of measure are determined by the underlying part definition. For example, if the part is defined with a default unit of measure of "kg", the user can specify the required quantity in "g", "mg", "lb", etc. + +The `raw_amount` field is stored as a string, and the `quantity` field is automatically calculated from the `raw_amount` field, taking into account the units of measure associated with the underlying part. This allows for greater flexibility in specifying the required quantity of a particular part, while still maintaining accurate tracking of inventory and production requirements. + +If the underlying part does not have a defined unit of measure, the `raw_amount` field is not allowed to have any units of measure specified, and the `quantity` field is simply a numeric representation of the `raw_amount` field. + +### Fractional Representation + +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. + ### 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. @@ -37,6 +50,12 @@ 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*. +### 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. + +When completing a Build Order, the user can choose whether to include optional items in the build process or not. If optional items are included, they will be allocated to the Build Order as normal. If optional items are excluded, they will not be allocated to the Build Order, and the build process can be completed without them. + ### Substitute BOM Line Items Where alternative parts can be used when building an assembly, these parts are assigned as *Substitute* parts in the Bill of Materials. A particular line item may have multiple substitute parts assigned to it. When allocating stock to a [Build Order](./build.md), stock items associated with any of the substitute parts may be allocated against the particular line item. @@ -86,13 +105,20 @@ Note that inherited BOM Line Items only flow "downwards" in the variant inherita !!! info "Editing Inherited Items" When editing an inherited BOM Line Item for a template part, the changes are automatically reflected in the BOM of any variant parts. -## BOM Creation +## BOM Editing -BOMs can be created manually, by adjusting individual line items, or by uploading (importing) an existing BOM file. +Bills of Material (BOMs) can be created manually, by adjusting individual line items, or by uploading (importing) an existing BOM file. + +### Editing Mode + +By default, the BOM is displayed in "view" mode. To edit the BOM, click on the {{ icon("edit", color="blue", title="Edit") }} icon at the top of the BOM panel. This will enable editing mode, which allows you to add, adjust or delete BOM line items. + +!!! warning "Permissions" + Only users with the appropriate permissions can edit BOMs. If you do not have permission to edit the BOM, the "Edit" icon will not be visible. ### Importing a BOM -BOM data can be imported from an existing file (such as CSV or Excel) from the *BOM* panel for a particular part/assembly. This process is a special case of the more general [data import process](../settings/import.md). +BOM data can be imported from an existing file (such as CSV or Excel) from the *BOM* panel for a particular part/assembly. This process is a special case of the more general [data import process](../concepts/data_import.md). At the top of the *BOM* panel, click on the {{ icon("file-arrow-left", color="green", title="Import BOM Data") }} icon to open the import dialog. @@ -156,89 +182,40 @@ If the BOM requires revalidation, the status will be displayed as "Not Validated {{ image("build/bom_invalid.png", "BOM Not Validated") }} -## Required Quantity Calculation +## BOM Comparison -When a new [Build Order](./build.md) is created, the required production quantity of each component part is calculated based on the BOM line items defined for the assembly being built. To calculate the required production quantity of a component part, the following considerations are made: +It is possible to compare the BOM of one assembly with another assembly. This comparison can highlight different component parts, quantities and other properties of the BOM line items. -### Base Quantity +To compare the BOM of one assembly with another, navigate to the "Bill of Materials" tab of the part detail page, then click on the {{ icon("git-compare", color="blue", title="Compare BOM") }} icon at the top of the BOM table: -The base quantity of a BOM line item is defined by the `Quantity` field of the BOM line item. This is the number of parts which are required to build one assembly. This value is multiplied by the number of assemblies which are being built to determine the total quantity of parts required. +{{ image("build/bom_compare_icon.png", "BOM Compare") }} -``` -Required Quantity = Base Quantity * Number of Assemblies -``` +This will open the BOM comparison view, which allows you to select a secondary assembly to compare with the primary assembly. The BOM line items of the two assemblies will be displayed side by side, with differences highlighted: -### Attrition +{{ image("build/bom_compare.png", "BOM Compare") }} -The `Attrition` field of a BOM line item is used to account for expected losses during the production process. This is expressed as a percentage of the `Base Quantity` (e.g. 2%). +### Display Mode -If a non-zero attrition percentage is specified, it is applied to the calculated `Required Quantity` value. +When comparing BOMs from two different assemblies, the user can select from the following view modes: -``` -Required Quantity = Required Quantity * (1 + Attrition Percentage) -``` +| View Mode | Description | +| --- | --- | +| *Show all parts* | Display all BOM line items from both assemblies. Differences are highlighted. | +| *Show different parts* | Display only the BOM line items which are different between the two assemblies. | +| *Show common parts* | Display only the BOM line items which are common between the two assemblies. | -!!! info "Optional" - The attrition percentage is optional. If not specified, it defaults to 0%. +In each case, any differences between the BOM line items are highlighted in red. -### Setup Quantity +## Replacing Components -The `Setup Quantity` field of a BOM line item is used to account for fixed losses during the production process. This is an additional quantity of the part which is required to ensure that the production run can be completed successfully. This value is added to the calculated `Required Quantity`. +When a component is used in the BOM for multiple assemblies, it can be time consuming to update the BOM for each assembly when a change is required. InvenTree provides a "Replace Component" function which streamlines the process of replacing a component part with another part across multiple BOMs. -``` -Required Quantity = Required Quantity + Setup Quantity -``` +To replace a component part within multiple assemblies: -!!! info "Optional" - The setup quantity is optional. If not specified, it defaults to 0. +- Navigate to the [Used In](../part/views.md#used-in) tab of the component part detail page +- Select the assemblies you wish to update by ticking the checkbox next to each assembly +- Click on the {{ icon("replace", color="blue", title="Replace Component") }} icon to open the "Replace Component" dialog -### Rounding Multiple +The following dialog will be displayed, which allows the user to select a new component part to replace the existing component part in the BOM of the selected assemblies: -The `Rounding Multiple` field of a BOM line item is used to round the calculated `Required Quantity` value to the nearest multiple of the specified value. This is useful for ensuring that the required quantity is a whole number, or to meet specific packaging requirements. - -``` -Required Quantity = ceil(Required Quantity / Rounding Multiple) * Rounding Multiple -``` - -!!! info "Optional" - The rounding multiple is optional. If not specified, no rounding is applied to the calculated production quantity. - -### Example Calculation - -Consider a BOM line item with the following properties: - -- Base Quantity: 3 -- Attrition: 2% (0.02) -- Setup Quantity: 10 -- Rounding Multiple: 25 - -If we are building 100 assemblies, the required quantity would be calculated as follows: - -``` -Required Quantity = Base Quantity * Number of Assemblies - = 3 * 100 - = 300 - -Attrition Value = Required Quantity * Attrition Percentage - = 300 * 0.02 - = 6 - -Required Quantity = Required Quantity + Attrition Value - = 300 + 6 - = 306 - -Required Quantity = Required Quantity + Setup Quantity - = 306 + 10 - = 316 - -Required Quantity = ceil(Required Quantity / Rounding Multiple) * Rounding Multiple - = ceil(316 / 25) * 25 - = 13 * 25 - = 325 - -``` - -So the final required production quantity of the component part would be `325`. - -!!! info "Calculation" - The required quantity calculation is performed automatically when a new [Build Order](./build.md) is created. +{{ image("build/replace_component.png", "Replace Component") }} diff --git a/docs/docs/manufacturing/build.md b/docs/docs/manufacturing/build.md index 3a8b5b8fc8..496e2c1dde 100644 --- a/docs/docs/manufacturing/build.md +++ b/docs/docs/manufacturing/build.md @@ -304,10 +304,11 @@ The following [global settings](../settings/global.md) are available for adjusti | Name | Description | Default | Units | | ---- | ----------- | ------- | ----- | {{ globalsetting("BUILDORDER_REFERENCE_PATTERN") }} -{{ globalsetting("BUILDORDER_EXTERNAL_BUILDS") }} {{ globalsetting("BUILDORDER_REQUIRE_RESPONSIBLE") }} {{ globalsetting("BUILDORDER_REQUIRE_ACTIVE_PART") }} {{ globalsetting("BUILDORDER_REQUIRE_LOCKED_PART") }} {{ globalsetting("BUILDORDER_REQUIRE_VALID_BOM") }} {{ globalsetting("BUILDORDER_REQUIRE_CLOSED_CHILDS") }} {{ globalsetting("PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS") }} +{{ globalsetting("BUILDORDER_EXTERNAL_BUILDS") }} +{{ globalsetting("BUILDORDER_EXTERNAL_REQUIRED") }} diff --git a/docs/docs/manufacturing/required.md b/docs/docs/manufacturing/required.md new file mode 100644 index 0000000000..949277b9ab --- /dev/null +++ b/docs/docs/manufacturing/required.md @@ -0,0 +1,90 @@ +--- +title: Required Build Quantity +--- + +## Required Build Quantity + +When a new [Build Order](./build.md) is created, the required production quantity of each component part is calculated based on the BOM line items defined for the assembly being built. To calculate the required production quantity of a component part, the following considerations are made: + +### Base Quantity + +The base quantity of a BOM line item is defined by the `Quantity` field of the BOM line item. This is the number of parts which are required to build one assembly. This value is multiplied by the number of assemblies which are being built to determine the total quantity of parts required. + +``` +Required Quantity = Base Quantity * Number of Assemblies +``` + +### Attrition + +The `Attrition` field of a BOM line item is used to account for expected losses during the production process. This is expressed as a percentage of the `Base Quantity` (e.g. 2%). + +If a non-zero attrition percentage is specified, it is applied to the calculated `Required Quantity` value. + +``` +Required Quantity = Required Quantity * (1 + Attrition Percentage) +``` + +!!! info "Optional" + The attrition percentage is optional. If not specified, it defaults to 0%. + +### Setup Quantity + +The `Setup Quantity` field of a BOM line item is used to account for fixed losses during the production process. This is an additional quantity of the part which is required to ensure that the production run can be completed successfully. This value is added to the calculated `Required Quantity`. + +``` +Required Quantity = Required Quantity + Setup Quantity +``` + +!!! info "Optional" + The setup quantity is optional. If not specified, it defaults to 0. + +### Rounding Multiple + +The `Rounding Multiple` field of a BOM line item is used to round the calculated `Required Quantity` value to the nearest multiple of the specified value. This is useful for ensuring that the required quantity is a whole number, or to meet specific packaging requirements. + +``` +Required Quantity = ceil(Required Quantity / Rounding Multiple) * Rounding Multiple +``` + +!!! info "Optional" + The rounding multiple is optional. If not specified, no rounding is applied to the calculated production quantity. + +### Example Calculation + +Consider a BOM line item with the following properties: + +- Base Quantity: 3 +- Attrition: 2% (0.02) +- Setup Quantity: 10 +- Rounding Multiple: 25 + +If we are building 100 assemblies, the required quantity would be calculated as follows: + +``` +Required Quantity = Base Quantity * Number of Assemblies + = 3 * 100 + = 300 + +Attrition Value = Required Quantity * Attrition Percentage + = 300 * 0.02 + = 6 + +Required Quantity = Required Quantity + Attrition Value + = 300 + 6 + = 306 + +Required Quantity = Required Quantity + Setup Quantity + = 306 + 10 + = 316 + +Required Quantity = ceil(Required Quantity / Rounding Multiple) * Rounding Multiple + = ceil(316 / 25) * 25 + = 13 * 25 + = 325 + +``` + +So the final required production quantity of the component part would be `325`. + +!!! info "Calculation" + The required quantity calculation is performed automatically when a new [Build Order](./build.md) is created. diff --git a/docs/docs/part/create.md b/docs/docs/part/create.md index d9b984e0e6..842e2133e5 100644 --- a/docs/docs/part/create.md +++ b/docs/docs/part/create.md @@ -20,7 +20,7 @@ New parts can be created manually by selecting the *Create Part* option from the {{ image("part/part_create_form.png", "New part form") }} -Fill out the required part parameters and then press *Submit* to create the new part. If there are any form errors, you must fix these before the form can be successfully submitted. +Fill out the required attributes and then press *Submit* to create the new part. If there are any form errors, you must fix these before the form can be successfully submitted. Once the form is completed, the browser window is redirected to the new part detail page. @@ -48,7 +48,7 @@ If the *Add Supplier Data* option is checked, then supplier part and manufacture Parts can be imported from an external file, by selecting the *Import from File* option. -This action opens the [data import wizard](../settings/import.md), which steps the user through the process of importing parts from the selected file. +This action opens the [data import wizard](../concepts/data_import.md), which steps the user through the process of importing parts from the selected file. ## Import from Supplier diff --git a/docs/docs/part/index.md b/docs/docs/part/index.md index e4848ece1f..1c7d048268 100644 --- a/docs/docs/part/index.md +++ b/docs/docs/part/index.md @@ -6,6 +6,18 @@ title: Parts The *Part* is the core element of the InvenTree ecosystem. A Part object is the archetype of any stock item in your inventory. Parts are arranged in hierarchical categories which are used to organize and filter parts by function. +## Part Stock + +Each part can have multiple [stock items](../stock/index.md) associated with it, which represent the physical quantity of that part in various locations. The total stock level for a given part is the sum of all stock items associated with that part. + +### Minimum Stock + +A part may have a specified "minimum stock" level. This is a user-defined value which indicates the minimum quantity of that part which should be kept in stock at all times. If the total stock level for a given part falls below the minimum stock level, the part is flagged as "low stock" and can be easily identified in the interface. + +### Maximum Stock + +A part may also have a specified "maximum stock" level. This is a user-defined value which indicates the maximum quantity of that part which should be kept in stock at all times. If the total stock level for a given part exceeds the maximum stock level, the part is flagged as "overstocked" and can be easily identified in the interface. + ## Part Category Part categories are very flexible and can be easily arranged to match a particular user requirement. Each part category displays a list of all parts *under* that given category. This means that any part belonging to a particular category, or belonging to a sub-category, will be displayed. @@ -27,7 +39,7 @@ Clicking on the part name links to the [*Part Detail*](./views.md) view. ## Part Attributes -Each *Part* defined in the database provides a number of different attributes which determine how that part can be used. Configuring these attributes for a given part will impact the available functions that can be perform on (or using) that part). +Each *Part* defined in the database provides a number of different attributes which determine how that part can be used. Configuring these attributes for a given part will impact the available functions that can be perform on (or using) that part. ### Virtual @@ -75,13 +87,16 @@ 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. + ## Locked Parts Parts can be locked to prevent them from being modified. This is useful for parts which are in production and should not be changed. The following restrictions apply to parts which are locked: - Locked parts cannot be deleted - BOM items cannot be created, edited, or deleted when they are part of a locked assembly -- Part parameters linked to a locked part cannot be created, edited or deleted +- Parameters linked to a locked part cannot be created, edited or deleted + +The part locking functionality can be enabled or disabled globally via the [Part Locking](../settings/global.md#parts) system setting (`PART_ENABLE_LOCKING`). When disabled, the locked state of a part is ignored and all operations are permitted. ## Active Parts @@ -145,4 +160,4 @@ The [InvenTree mobile app](../app/part.md#part-image-view) allows part images to ## Part Import -*Parts* can be imported by staff-members on the part-list-view (this feature must be enabled in the part-settings), in the part-settings or on the [admin-page for parts](../settings/import.md) (only accessible if you are also an admin). The first two options provide a multi-stage wizard that enables mapping fields from various spreadsheet or table-data formats while the latter requires a well-formatted file but is much more performant. +*Part* data can be imported using the [data import wizard](../concepts/data_import.md). This allows part data to be imported from an external file, which can be useful for bulk importing of part data. diff --git a/docs/docs/part/revision.md b/docs/docs/part/revision.md index fe7d94304d..2e86019351 100644 --- a/docs/docs/part/revision.md +++ b/docs/docs/part/revision.md @@ -27,24 +27,22 @@ When creating a new revision of a part, there are some restrictions which must b * **Circular References**: A part cannot be a revision of itself. This would create a circular reference which is not allowed. * **Unique Revisions**: A part cannot have two revisions with the same revision number. Each revision (of a given part) must have a unique revision code. -* **Revisions of Revisions**: A single part can have multiple revisions, but a revision cannot have its own revision. This restriction is in place to prevent overly complex part relationships. * **Template Revisions**: A part which is a [template part](./template.md) cannot have revisions. This is because the template part is used to create variants, and allowing revisions of templates would create disallowed relationship states in the database. However, variant parts are allowed to have revisions. * **Template References**: A part which is a revision of a variant part must point to the same template as the original part. This is to ensure that the revision is correctly linked to the original part. ## Revision Settings -The following options are available to control the behavior of part revisions. +The following [global settings](../settings/global.md) are available to control the behavior of part revisions: -Note that these options can be changed in the InvenTree settings: +| Name | Description | Default | Units | +| ---- | ----------- | ------- | ----- | +{{ globalsetting("PART_ENABLE_REVISION") }} +{{ globalsetting("PART_REVISION_ASSEMBLY_ONLY") }} -{{ image("part/part_revision_settings.png", "Part revision settings") }} - -* **Enable Revisions**: If this setting is enabled, parts can have revisions. If this setting is disabled, parts cannot have revisions. -* **Assembly Revisions Only**: If this setting is enabled, only assembly parts can have revisions. This is useful if you only want to track revisions of assemblies, and not individual parts. ## Create a Revision -To create a new revision for a given part, navigate to the part detail page, and click on the "Revisions" tab. +To create a new revision for a given part, navigate to the part detail page, and click on the part actions menu (three vertical dots on the top right of the page). Select the "Duplicate Part" action, to create a new copy of the selected part. This will open the "Duplicate Part" form: @@ -67,4 +65,5 @@ When multiple revisions exist for a particular part, you can navigate between re {{ image("part/part_revision_select.png", "Select part revision") }} -Note that this revision selector is only visible when multiple revisions exist for the part. +!!! info "Revision Selector Visibility" + Note that this revision selector is only visible when multiple revisions exist for the part. diff --git a/docs/docs/plugins/develop.md b/docs/docs/plugins/develop.md index 0522f4ea34..fb6bfbec57 100644 --- a/docs/docs/plugins/develop.md +++ b/docs/docs/plugins/develop.md @@ -41,7 +41,7 @@ If you want to make your life easier, try to follow these guidelines; break wher from plugin import InvenTreePlugin, registry from plugin.mixins import APICallMixin, SettingsMixin, ScheduleMixin, BarcodeMixin ``` -- Feliver as a package (see [below](#packaging)) +- Deliver as a package (see [below](#packaging)) - If you need to use a private infrastructure, use the 'Releases' functions in GitHub or Gitlab. Point to the 'latest' release endpoint when installing to make sure the update function works - Tag your GitHub repo with `inventree` and `inventreeplugins` to make discovery easier. A discovery mechanism using these tags is on the roadmap. - Use GitHub actions to test your plugin regularly (you can [schedule actions](https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#schedule)) against the 'latest' [docker-build](https://hub.docker.com/r/inventree/inventree) of InvenTree diff --git a/docs/docs/plugins/frontend.md b/docs/docs/plugins/frontend.md index 0df93fd49d..550a604590 100644 --- a/docs/docs/plugins/frontend.md +++ b/docs/docs/plugins/frontend.md @@ -10,6 +10,9 @@ Plugins can inherit from the [UserInterfaceMixin](./mixins/ui.md) class to provi Note that the [InvenTree plugin creator](./creator.md) can be used to scaffold a new plugin with the necessary structure for frontend integration. This will automatically set up the necessary files and configurations to get started with frontend development. +!!! info "Simplified Development" + Using the plugin creator can significantly simplify the process of developing a frontend plugin, as it provides a ready-made template with the necessary configurations for building and integrating the frontend code. Rolling your own frontend plugin from scratch is possible, but it requires a good understanding of the InvenTree frontend architecture and build process. + ## Frontend Architecture When designing a frontend plugin component, it is important to have at least a basic understanding of the InvenTree frontend architecture. @@ -76,20 +79,28 @@ The following properties are available in the `context` object: | Property | Description | | -------- | ----------- | | `version` | An object containing the current InvenTree version information. | +| `api` | The Axios instance configured to communicate with the InvenTree API. | +| `queryClient` | The query client instance used for managing API calls in the frontend. | | `user` | An object containing information about the currently logged-in user. | +| `userSettings` | An object containing user-specific settings. | +| `globalSettings` | An object containing global settings for the InvenTree instance. | +| `modelInformation` | An object containing information about the models available in the InvenTree instance. | +| `renderInstance` | A function to render a model instance | | `host` | An object containing information about the current host (server) configuration. | | `i18n` | An object containing internationalization (i18n) functions for translating text. | | `locale` | The current locale being used for the user interface. | -| `api` | The Axios instance configured to communicate with the InvenTree API. | -| `queryClient` | The query client instance used for managing API calls in the frontend. | | `navigate` | A function to navigate to a different page in the InvenTree web interface. | -| `globalSettings` | An object containing global settings for the InvenTree instance. | -| `userSettings` | An object containing user-specific settings. | -| `modelInformation` | An object containing information about the models available in the InvenTree instance. | -| `renderInstance` | A function to render a model instance | | `theme` | The current Mantine theme being used in the InvenTree web interface. | | `colorScheme` | The current color scheme being used in the InvenTree web interface. | | `forms` | A set of functional components for rendering forms in the InvenTree web interface. | +| `tables` | A set of functional components for rendering tables in the InvenTree web interface. | +| `importer` | A set of functions for controlling the global importer drawer in the InvenTree web interface. | +| `model` | The model type associated with the rendered component (if applicable). | +| `id` | The ID (primary key) of the model instance being rendered (if applicable). | +| `instance` | The model instance data (if available). | +| `reloadContent` | A function which can be called to reload the plugin content. | +| `reloadInstance` | A function which can be called to reload the model instance. | +| `context` | Any additional context data which may be passed to the plugin. | This set of components is passed through at render time to the plugin function, allowing the plugin code to hook directly into the InvenTree web interface and access the necessary context for rendering. diff --git a/docs/docs/plugins/install.md b/docs/docs/plugins/install.md index 3d18d58850..6f2f9f5fd6 100644 --- a/docs/docs/plugins/install.md +++ b/docs/docs/plugins/install.md @@ -74,6 +74,9 @@ Enter the package name into the form as shown below. You can add a path and a ve {{ image("plugin/plugin_install_txt.png", "Plugin.txt file") }} +!!! info "Superuser Required" + Only users with superuser privileges can manage plugins via the web interface. + #### Local Directory Custom plugins can be placed in the `data/plugins/` directory, where they will be automatically discovered. This can be useful for developing and testing plugins, but can prove more difficult in production (e.g. when using Docker). diff --git a/docs/docs/plugins/mixins/app.md b/docs/docs/plugins/mixins/app.md index e607bc7b52..895341d4c6 100644 --- a/docs/docs/plugins/mixins/app.md +++ b/docs/docs/plugins/mixins/app.md @@ -8,3 +8,27 @@ If this mixin is added to a plugin the directory the plugin class is defined in !!! warning "Danger Zone" Only use this mixin if you have an understanding of Django's [app system]({% include "django.html" %}/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of Django to make sure your code does not cause unwanted behaviour in InvenTree before releasing. + +## Custom Models + +This mixin allows you to define custom database models within your plugin. These models will be automatically registered with the InvenTree server, and will be available for use within your plugin code. + +### Model Permissions + +Some database operations within the InvenTree ecosystem may require custom permissions checks - to determine which actions a user can perform against a given model. If your plugin defines custom models, you may need to implement a custom permission check method on your model class. + +Each model class can implement a `check_user_permission` classmethod, which will be called by the InvenTree permission system when checking permissions for that model. This method should return `True` if the user has the required permissions, and `False` otherwise. + + +```python +class MyCustomModel(models.Model): + # model fields here + + @classmethod + def check_user_permission(cls, user: User, permission: str) -> bool: + # custom permission logic here + return True # or False +``` + +!!! warning "Default Permissions" + By default, if the `check_user_permission` method is not implemented, the InvenTree permission system will return `False` for all permission checks against that model. This is to ensure that no permissions are granted by default, and that the plugin developer must explicitly define the required permissions for their custom models. diff --git a/docs/docs/plugins/mixins/event.md b/docs/docs/plugins/mixins/event.md index c2f048b055..f3f61a0d1e 100644 --- a/docs/docs/plugins/mixins/event.md +++ b/docs/docs/plugins/mixins/event.md @@ -13,6 +13,9 @@ When a certain (server-side) event occurs, the background worker passes the even {{ image("plugin/enable_events.png", "Enable event integration") }} +!!! info "Worker debugging" + As the events are offloaded to a background worker debugging the `process_event()` function need some extra consideration. Please see the [Run background workers](../../develop/devcontainer.md#run-background-workers) section for further information. + ## Events Events are passed through using a string identifier, e.g. `build.completed` diff --git a/docs/docs/plugins/mixins/ui.md b/docs/docs/plugins/mixins/ui.md index 90329832c2..dc3785d778 100644 --- a/docs/docs/plugins/mixins/ui.md +++ b/docs/docs/plugins/mixins/ui.md @@ -183,6 +183,20 @@ The `get_ui_template_previews` feature type can be used to provide custom templa summary: False members: [] +### Primary Actions + +The `get_ui_primary_actions` method can be used to provide custom primary action, which are rendered in the header of the page, next to the title/name and any status indicators. These primary actions are typically used to provide quick access to common actions related to the current page. + +::: plugin.base.ui.mixins.UserInterfaceMixin.get_ui_primary_actions + options: + show_bases: False + show_root_heading: False + show_root_toc_entry: False + extra: + show_source: True + summary: False + members: [] + ## Plugin Context When rendering certain content in the user interface, the rendering functions are passed a `context` object which contains information about the current page being rendered. The type of the `context` object is defined in the `PluginContext` file: diff --git a/docs/docs/plugins/test.md b/docs/docs/plugins/test.md index 775da49c03..a1eddd8912 100644 --- a/docs/docs/plugins/test.md +++ b/docs/docs/plugins/test.md @@ -9,11 +9,10 @@ For complicated plugins it makes sense to add unit tests the code to ensure that For plugin testing the following environment variables must be set to True: -| Name | Function | Value | -| ---- | -------- | ----- | -| INVENTREE_PLUGINS_ENABLED | Enables the use of 3rd party plugins | True | -| INVENTREE_PLUGIN_TESTING | Enables enables all plugins no matter of their active state in the db or built-in flag | True | -| INVENTREE_PLUGIN_TESTING_SETUP | Enables the url mixin | True | +{{ configtable() }} +{{ configsetting("INVENTREE_PLUGINS_ENABLED") }} Enables the use of 3rd party plugins | +{{ configsetting("INVENTREE_PLUGIN_TESTING") }} Enables enables all plugins no matter of their active state in the db or built-in flag | +{{ configsetting("INVENTREE_PLUGIN_TESTING_SETUP") }} Enables the url mixin | ### Test Program diff --git a/docs/docs/report/helpers.md b/docs/docs/report/helpers.md index 79fde22b2f..c8811f561c 100644 --- a/docs/docs/report/helpers.md +++ b/docs/docs/report/helpers.md @@ -173,8 +173,144 @@ Generate a list of all active customers: More advanced database filtering should be achieved using a [report plugin](../plugins/mixins/report.md), and adding custom context data to the report template. +## List Helpers + +The following helper functions are available for working with list (or list-like) data structures: + +### length + +Return the length of a list (or list-like) data structure. Note that this will also work for other data structures which support the `len()` function, such as strings, dictionaries or querysets: + +::: report.templatetags.report.length + options: + show_docstring_description: false + show_source: False + +### first + +Return the first element of a list (or list-like) data structure: + +::: report.templatetags.report.first + options: + show_docstring_description: false + show_source: False + + +### last + +Return the last element of a list (or list-like) data structure: + +::: report.templatetags.report.last + options: + show_docstring_description: false + show_source: False + +### reverse + +Return a list (or list-like) data structure in reverse order: + +::: report.templatetags.report.reverse + options: + show_docstring_description: false + show_source: False + +### truncate + +Return a truncated version of a list (or list-like) data structure, containing only the first N elements: + +::: report.templatetags.report.truncate + options: + show_docstring_description: false + show_source: False + +## String Formatting + +### strip + +Return a string with leading and trailing whitespace removed: + +::: report.templatetags.report.strip + options: + show_docstring_description: false + show_source: False + + +### lstrip + +Return a string with leading whitespace removed: + +::: report.templatetags.report.lstrip + options: + show_docstring_description: false + show_source: False + +### rstrip + +Return a string with trailing whitespace removed: + +::: report.templatetags.report.rstrip + options: + show_docstring_description: false + show_source: False + +### split + +Return a list of substrings by splitting a string based on a specified separator: + +::: report.templatetags.report.split + options: + show_docstring_description: false + show_source: False + +### join + +Return a string by joining a list of strings into a single string, using a specified separator: + +::: report.templatetags.report.join + options: + show_docstring_description: false + show_source: False + +### replace + +Return a string where occurrences of a specified substring are replaced with another substring: + +::: report.templatetags.report.replace + options: + show_docstring_description: false + show_source: False + +### lowercase + +Return a string with all characters converted to lowercase: + +::: report.templatetags.report.lowercase + options: + show_docstring_description: false + show_source: False + +### uppercase + +Return a string with all characters converted to uppercase: + +::: report.templatetags.report.uppercase + options: + show_docstring_description: false + show_source: False + +### titlecase + +Return a string with the first character of each word converted to uppercase and the remaining characters converted to lowercase: + +::: report.templatetags.report.titlecase + options: + show_docstring_description: false + show_source: False + ## Number Formatting +A number of helper functions are available for formatting numbers in a particular way. These can be used to format numbers according to a particular number of decimal places, or to add leading zeros, for example. + ### format_number The helper function `format_number` allows for some common number formatting options. It takes a number (or a number-like string) as an input, as well as some formatting arguments. It returns a *string* containing the formatted number: @@ -547,14 +683,18 @@ You can add asset images to the reports and labels by using the `{% raw %}{% ass ## Parameters -If you need to load a parameter value for a particular model instance, within the context of your template, you can use the `parameter` template tag: +If you need to reference a parameter for a particular model instance, within the context of your template, you can use the `parameter` template tag: + +### parameter + +This returns a [Parameter](../concepts/parameters.md) object which contains the value of the parameter, as well as any associated metadata (e.g. units, description, etc). ::: report.templatetags.report.parameter options: show_docstring_description: false show_source: False -### Example +#### Example The following example assumes that you have a report or label which contains a valid [Part](../part/index.md) instance: @@ -580,6 +720,27 @@ A [Parameter](../concepts/parameters.md) has the following available attributes: | Units | The *units* of the parameter (e.g. "km") | | Template | A reference to a [ParameterTemplate](../concepts/parameters.md#parameter-templates) | +### parameter_value + +To access just the value of a parameter, use the `parameter_value` template tag: + +::: report.templatetags.report.parameter_value + options: + show_docstring_description: false + show_source: False + +#### Example + +``` +{% raw %} +{% load report %} + +{% parameter_value part "length" backup_value="3"as length_value %} +Part: {{ part.name }}
+Length: {{ length_value }} +{% endraw %} +``` + ## Rendering Markdown Some data fields (such as the *Notes* field available on many internal database models) support [markdown formatting](https://en.wikipedia.org/wiki/Markdown). To render markdown content in a custom report, there are template filters made available through the [django-markdownify](https://github.com/erwinmatijsen/django-markdownify) library. This library provides functionality for converting markdown content to HTML representation, allowing it to be then rendered to PDF by the InvenTree report generation pipeline. diff --git a/docs/docs/sales/sales_order.md b/docs/docs/sales/sales_order.md index ebdf3d2e69..d1c8a790ff 100644 --- a/docs/docs/sales/sales_order.md +++ b/docs/docs/sales/sales_order.md @@ -234,3 +234,4 @@ The following [global settings](../settings/global.md) are available for sales o {{ globalsetting("SALESORDER_EDIT_COMPLETED_ORDERS") }} {{ globalsetting("SALESORDER_SHIP_COMPLETE") }} {{ globalsetting("SALESORDER_SHIPMENT_REQUIRES_CHECK") }} +{{ globalsetting("SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS")}} diff --git a/docs/docs/settings/SSO.md b/docs/docs/settings/SSO.md index 62849500b1..ab7d3a539c 100644 --- a/docs/docs/settings/SSO.md +++ b/docs/docs/settings/SSO.md @@ -29,10 +29,10 @@ The first step is to ensure that the required provider modules are installed, vi There are two variables in the configuration file which define the operation of SSO: -| Environment Variable |Configuration File | Description | More Info | -| --- | --- | --- | --- | -| INVENTREE_SOCIAL_BACKENDS | `social_backends` | A *list* of provider backends enabled for the InvenTree instance | [django-allauth docs](https://docs.allauth.org/en/latest/installation/quickstart.html) | -| INVENTREE_SOCIAL_PROVIDERS | `social_providers` | A *dict* of settings specific to the installed providers | [provider documentation](https://docs.allauth.org/en/latest/socialaccount/providers/index.html) | +{{ configtable() }} +{{ configsetting("INVENTREE_SOCIAL_BACKENDS") }} A *list* of [social provider backends](https://docs.allauth.org/en/latest/installation/quickstart.html) enabled for the InvenTree instance | +{{ configsetting("INVENTREE_SOCIAL_PROVIDERS") }} A *dict* of settings specific to the [installed providers](https://docs.allauth.org/en/latest/socialaccount/providers/index.html) | + In the example below, SSO provider modules are activated for *google*, *github* and *microsoft*. Specific configuration options are specified for the *microsoft* provider module: diff --git a/docs/docs/settings/admin.md b/docs/docs/settings/admin.md index 8b5fa57ea7..039ba0e026 100644 --- a/docs/docs/settings/admin.md +++ b/docs/docs/settings/admin.md @@ -55,19 +55,12 @@ The admin interface allows *staff* users the ability to directly view / add / ed #### Access Backend Admin Interface -To access the admin interface, select the "Admin" option from the drop-down user menu in the top-right corner of the screen. - - -!!! info "Staff Only" - Only users with staff access will be able to see the "Admin" option +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") }} -!!! info "Admin URL" - To directly access the admin interface, append /admin/ to the InvenTree site URL - e.g. http://localhost:8000/admin/ - #### View Database Objects Database objects can be listed and filtered directly. The image below shows an example of displaying existing part categories. diff --git a/docs/docs/settings/error_codes.md b/docs/docs/settings/error_codes.md index 59874a9402..120bbc5b56 100644 --- a/docs/docs/settings/error_codes.md +++ b/docs/docs/settings/error_codes.md @@ -105,6 +105,11 @@ A potentially critical mismatch between the backup environment and the current r While using [invoke](../start/invoke.md), this can be overridden with the `--restore-allow-newer-version` flag. +#### INVE-E17 +**Error rendering component** + +An error occurred while rendering a component in the frontend. Typically this is caused by a browser caching issue, and can be resolved by clearing the browser cache and refreshing the page. If the issue persists, check the browser console for more information about the error. + ### INVE-W (InvenTree Warning) Warnings - These are non-critical errors which should be addressed when possible. @@ -210,6 +215,17 @@ The environment in which the backup was taken does not match the current environ This warning will not prevent you from restoring the backup but it is recommended to ensure the mentioned issues are resolved before restoring the backup to prevent issues with the restored instance. +#### INVE-W14 +**Elevated privileges - Backend** + +A user is logged in with elevated privileges. This might be a superuser or a administrator user. These types of users have elevated permissions and should not be used for regular usage. +Use separate accounts for administrative tasks and regular usage to reduce risk. Make sure to review the [permission documentation](../settings/permissions.md#dangerous-user-flags). + +#### INVE-W15 +**Process interrupted by user - Backend** + +A process was interrupted by the user, likely by a keyboard interrupt. This might lead to issues with the process that was interrupted, as it might not have completed its task. This is especially relevant for processes that are not idempotent or that do not have a good rollback mechanism. + ### INVE-I (InvenTree Information) Information — These are not errors but information messages. They might point out potential issues or just provide information. diff --git a/docs/docs/settings/export.md b/docs/docs/settings/export.md deleted file mode 100644 index 4ab560454a..0000000000 --- a/docs/docs/settings/export.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Exporting Data ---- - -## Exporting Data - -InvenTree provides data export functionality for a variety of data types. Most data tables provide an "Download" button, which allows the user to export the data in a variety of formats. - -In the top right corner of the table, click the "Download" button to export the data in the table. - -{{ image("admin/export.png", "Download") }} - -This will present a dialog box with the available export options: - -{{ image("admin/export_options.png", "Export Dialog") }} - -## Plugin Support - -InvenTree plugins can also provide custom export functionality for specific data types. If a plugin provides export functionality, it will be listed in the export options. - -Refer to the [export plugin mixin documentation](../plugins/mixins/export.md) for more information on how to create export plugins. - -## API Export - -Data can also be exported via the InvenTree REST API, by appending the appropriate format suffix (and other export options) to the API endpoint URL. diff --git a/docs/docs/settings/global.md b/docs/docs/settings/global.md index d443084077..752ef1b910 100644 --- a/docs/docs/settings/global.md +++ b/docs/docs/settings/global.md @@ -27,14 +27,20 @@ Configuration of basic server settings: {{ globalsetting("INVENTREE_INSTANCE_TITLE") }} {{ globalsetting("INVENTREE_INSTANCE_ID", default="Randomly generated value") }} {{ globalsetting("INVENTREE_ANNOUNCE_ID") }} +{{ globalsetting("INVENTREE_SHOW_SUPERUSER_BANNER") }} +{{ globalsetting("INVENTREE_SHOW_ADMIN_BANNER") }} {{ globalsetting("INVENTREE_RESTRICT_ABOUT") }} {{ globalsetting("DISPLAY_FULL_NAMES") }} {{ globalsetting("DISPLAY_PROFILE_INFO") }} -{{ globalsetting("INVENTREE_UPDATE_CHECK_INTERVAL") }} -{{ globalsetting("INVENTREE_DOWNLOAD_FROM_URL") }} -{{ globalsetting("INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE") }} -{{ globalsetting("INVENTREE_DOWNLOAD_FROM_URL_USER_AGENT") }} +{{ globalsetting("WEEK_STARTS_ON") }} +{{ globalsetting("INVENTREE_UPLOAD_MAX_SIZE") }} {{ globalsetting("INVENTREE_STRICT_URLS") }} + +Configuration of various scheduled tasks: + +| Name | Description | Default | Units | +| ---- | ----------- | ------- | ----- | +{{ globalsetting("INVENTREE_UPDATE_CHECK_INTERVAL") }} {{ globalsetting("INVENTREE_BACKUP_ENABLE") }} {{ globalsetting("INVENTREE_BACKUP_DAYS") }} {{ globalsetting("INVENTREE_DELETE_TASKS_DAYS") }} @@ -156,6 +162,7 @@ Configuration of label printing: {{ globalsetting("PART_ALLOW_DUPLICATE_IPN") }} {{ globalsetting("PART_ALLOW_EDIT_IPN") }} {{ globalsetting("PART_ALLOW_DELETE_FROM_ASSEMBLY") }} +{{ globalsetting("PART_ENABLE_LOCKING") }} {{ globalsetting("PART_ENABLE_REVISION") }} {{ globalsetting("PART_REVISION_ASSEMBLY_ONLY") }} {{ globalsetting("PART_NAME_FORMAT") }} @@ -170,6 +177,7 @@ Configuration of label printing: {{ globalsetting("PART_SALABLE") }} {{ globalsetting("PART_VIRTUAL") }} {{ globalsetting("PART_COPY_BOM") }} +{{ globalsetting("PART_BOM_ALLOW_ZERO_QUANTITY") }} {{ globalsetting("PART_COPY_PARAMETERS") }} {{ globalsetting("PART_COPY_TESTS") }} {{ globalsetting("PART_CATEGORY_PARAMETERS") }} @@ -203,6 +211,8 @@ Configuration of stock item options | Name | Description | Default | Units | | ---- | ----------- | ------- | ----- | {{ globalsetting("SERIAL_NUMBER_GLOBALLY_UNIQUE") }} +{{ globalsetting("STOCK_ALLOW_EDIT_SERIAL") }} +{{ globalsetting("STOCK_ALLOW_DELETE_SERIALIZED") }} {{ globalsetting("STOCK_DELETE_DEPLETED_DEFAULT") }} {{ globalsetting("STOCK_BATCH_CODE_TEMPLATE") }} {{ globalsetting("STOCK_ENABLE_EXPIRY") }} @@ -232,6 +242,10 @@ Refer to the [sales order settings](../sales/sales_order.md#sales-order-settings Refer to the [return order settings](../sales/return_order.md#return-order-settings). +### Transfer Orders + +Refer to the [transfer order settings](../stock/transfer_order.md#transfer-order-settings). + ### Plugin Settings | Name | Description | Default | Units | diff --git a/docs/docs/settings/permissions.md b/docs/docs/settings/permissions.md index e98fb3aaff..6e169af8f5 100644 --- a/docs/docs/settings/permissions.md +++ b/docs/docs/settings/permissions.md @@ -28,7 +28,8 @@ InvenTree functionality is split into a number of distinct roles. A group will h | Role | Description | | ---- | ----------- | | **Admin** | The *admin* role is related to assigning user permissions. | -| **Build** | The *build* role is related to accessing Build Order and Bill of Materials data | +| **BOM** | The *bom* role is related to accessing Bill of Materials data | +| **Build** | The *build* role is related to accessing manufacturing / Build Order | | **Part** | The *part* role is related to accessing Part data | | **Part Category** | The *part category* role is related to accessing Part Category data | | **Purchase Order** | The *purchase* role is related to accessing Purchase Order data | @@ -50,6 +51,17 @@ Within each role, there are four levels of available permissions: | **Add** | The *add* permission allows the user to add / create database records associated with the particular role | | **Delete** | The *delete* permission allows the user to delete / remove database records associated with the particular role | +## 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. +- **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. + +Practicing account tiering is strongly recommended. + + ## Admin Interface Permissions If a user does not have the required permissions to perform a certain action in the admin interface, those options not be displayed. diff --git a/docs/docs/settings/user.md b/docs/docs/settings/user.md index faaa7aae8a..fc8a1664cb 100644 --- a/docs/docs/settings/user.md +++ b/docs/docs/settings/user.md @@ -27,8 +27,10 @@ The *Display Settings* screen shows general display configuration options: {{ usersetting("FORMS_CLOSE_USING_ESCAPE") }} {{ usersetting("DISPLAY_STOCKTAKE_TAB") }} {{ usersetting("SHOW_FULL_CATEGORY_IN_TABLES")}} +{{ usersetting("SHOW_BOM_SUBASSEMBLY_LEVELS")}} {{ usersetting("ENABLE_LAST_BREADCRUMB") }} {{ usersetting("SHOW_FULL_LOCATION_IN_TABLES") }} +{{ usersetting("DISPLAY_ITEMS_FINAL_LEVEL") }} ### Search Settings diff --git a/docs/docs/start/advanced.md b/docs/docs/start/advanced.md index 14d8af5a3c..9bacc83924 100644 --- a/docs/docs/start/advanced.md +++ b/docs/docs/start/advanced.md @@ -51,46 +51,44 @@ You can link your InvenTree server to an LDAP server. Next you can start configuring the connection. Either use the config file or set the environment variables. -| config key | ENV Variable | Description | -| --- | --- | --- | -| `ldap.enabled` | `INVENTREE_LDAP_ENABLED` | Set this to `True` to enable LDAP. | -| `ldap.debug` | `INVENTREE_LDAP_DEBUG` | Set this to `True` to activate debug mode, useful for troubleshooting ldap configurations. | -| `ldap.server_uri` | `INVENTREE_LDAP_SERVER_URI` | LDAP Server URI, e.g. `ldaps://example.org` | -| `ldap.start_tls` | `INVENTREE_LDAP_START_TLS` | Enable TLS encryption over the standard LDAP port, [see](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-start-tls). (You can set TLS options via `ldap.global_options`) | -| `ldap.bind_dn` | `INVENTREE_LDAP_BIND_DN` | LDAP bind dn, e.g. `cn=admin,dc=example,dc=org` | -| `ldap.bind_password` | `INVENTREE_LDAP_BIND_PASSWORD` | LDAP bind password | -| `ldap.search_base_dn` | `INVENTREE_LDAP_SEARCH_BASE_DN` | LDAP search base dn, e.g. `cn=Users,dc=example,dc=org` | -| `ldap.user_dn_template` | `INVENTREE_LDAP_USER_DN_TEMPLATE` | use direct bind as auth user, `ldap.bind_dn` and `ldap.bin_password` is not necessary then, e.g. `uid=%(user)s,dc=example,dc=org` | -| `ldap.global_options` | `INVENTREE_LDAP_GLOBAL_OPTIONS` | set advanced options as dict, e.g. TLS settings. For a list of all available options, see [python-ldap docs](https://www.python-ldap.org/en/latest/reference/ldap.html#ldap-options). (keys and values starting with OPT_ get automatically converted to `python-ldap` keys) | -| `ldap.search_filter_str`| `INVENTREE_LDAP_SEARCH_FILTER_STR` | LDAP search filter str, default: `uid=%(user)s` | -| `ldap.user_attr_map` | `INVENTREE_LDAP_USER_ATTR_MAP` | LDAP <-> InvenTree user attribute map, can be json if used as env, in yml directly specify the object. default: `{"first_name": "givenName", "last_name": "sn", "email": "mail"}` | -| `ldap.always_update_user` | `INVENTREE_LDAP_ALWAYS_UPDATE_USER` | Always update the user on each login, default: `true` | -| `ldap.cache_timeout` | `INVENTREE_LDAP_CACHE_TIMEOUT` | cache timeout to reduce traffic with LDAP server, default: `3600` (1h) | -| `ldap.group_search` | `INVENTREE_LDAP_GROUP_SEARCH` | Base LDAP DN for group searching; required to enable group features | -| `ldap.group_object_class` | `INVENTREE_LDAP_GROUP_OBJECT_CLASS` | The string to pass to the LDAP group search `(objectClass=<...>)`, default: `groupOfUniqueNames` | -| `ldap.mirror_groups` | `INVENTREE_LDAP_MIRROR_GROUPS` | If `True`, mirror a user's LDAP group membership in the Django database, default: `False` | -| `ldap.group_type_class` | `INVENTREE_LDAP_GROUP_TYPE_CLASS` | The group class to be imported from `django_auth_ldap.config` as a string, default: `'GroupOfUniqueNamesType'`| -| `ldap.group_type_class_args` | `INVENTREE_LDAP_GROUP_TYPE_CLASS_ARGS` | A `list` of positional args to pass to the LDAP group type class, default `[]` | -| `ldap.group_type_class_kwargs` | `INVENTREE_LDAP_GROUP_TYPE_CLASS_KWARGS` | A `dict` of keyword args to pass to the LDAP group type class, default `{'name_attr': 'cn'}` | -| `ldap.require_group` | `INVENTREE_LDAP_REQUIRE_GROUP` | If set, users _must_ be in this group to log in to InvenTree | -| `ldap.deny_group` | `INVENTREE_LDAP_DENY_GROUP` | If set, users _must not_ be in this group to log in to InvenTree | -| `ldap.user_flags_by_group` | `INVENTREE_LDAP_USER_FLAGS_BY_GROUP` | LDAP group to InvenTree user flag map, can be json if used as env, in yml directly specify the object. See config template for example, default: `{}` | +{{ configtable() }} +{{ configsetting("INVENTREE_LDAP_ENABLED") }} Enable LDAP support | +{{ configsetting("INVENTREE_LDAP_DEBUG") }} Set this to `True` to activate debug mode, useful for troubleshooting ldap configurations. | +| `INVENTREE_LDAP_SERVER_URI` | `ldap.server_uri` | LDAP Server URI, e.g. `ldaps://example.org` | +| `INVENTREE_LDAP_START_TLS` | `ldap.start_tls` | Enable TLS encryption over the standard LDAP port, [see](https://django-auth-ldap.readthedocs.io/en/latest/reference.html#auth-ldap-start-tls). (You can set TLS options via `ldap.global_options`) | +| `INVENTREE_LDAP_BIND_DN` | `ldap.bind_dn` | LDAP bind dn, e.g. `cn=admin,dc=example,dc=org` | +| `INVENTREE_LDAP_BIND_PASSWORD` | `ldap.bind_password` | LDAP bind password | +| `INVENTREE_LDAP_SEARCH_BASE_DN` | `ldap.search_base_dn` | LDAP search base dn, e.g. `cn=Users,dc=example,dc=org` | +| `INVENTREE_LDAP_USER_DN_TEMPLATE` | `ldap.user_dn_template` | use direct bind as auth user, `ldap.bind_dn` and `ldap.bin_password` is not necessary then, e.g. `uid=%(user)s,dc=example,dc=org` | +| `INVENTREE_LDAP_GLOBAL_OPTIONS` | `ldap.global_options` | set advanced options as dict, e.g. TLS settings. For a list of all available options, see [python-ldap docs](https://www.python-ldap.org/en/latest/reference/ldap.html#ldap-options). (keys and values starting with OPT_ get automatically converted to `python-ldap` keys) | +| `INVENTREE_LDAP_SEARCH_FILTER_STR`| `ldap.search_filter_str` | LDAP search filter str, default: `uid=%(user)s` | +| `INVENTREE_LDAP_USER_ATTR_MAP` | `ldap.user_attr_map` | LDAP <-> InvenTree user attribute map, can be json if used as env, in yml directly specify the object. default: `{"first_name": "givenName", "last_name": "sn", "email": "mail"}` | +| `INVENTREE_LDAP_ALWAYS_UPDATE_USER` | `ldap.always_update_user` | Always update the user on each login, default: `true` | +| `INVENTREE_LDAP_CACHE_TIMEOUT` | `ldap.cache_timeout` | cache timeout to reduce traffic with LDAP server, default: `3600` (1h) | +| `INVENTREE_LDAP_GROUP_SEARCH` | `ldap.group_search` | Base LDAP DN for group searching; required to enable group features | +| `INVENTREE_LDAP_GROUP_OBJECT_CLASS` | `ldap.group_object_class` | The string to pass to the LDAP group search `(objectClass=<...>)`, default: `groupOfUniqueNames` | +| `INVENTREE_LDAP_MIRROR_GROUPS` | `ldap.mirror_groups` | If `True`, mirror a user's LDAP group membership in the Django database, default: `False` | +| `INVENTREE_LDAP_GROUP_TYPE_CLASS` | `ldap.group_type_class` | The group class to be imported from `django_auth_ldap.config` as a string, default: `'GroupOfUniqueNamesType'`| +| `INVENTREE_LDAP_GROUP_TYPE_CLASS_ARGS` | `ldap.group_type_class_args` | A `list` of positional args to pass to the LDAP group type class, default `[]` | +| `INVENTREE_LDAP_GROUP_TYPE_CLASS_KWARGS` | `ldap.group_type_class_kwargs` | A `dict` of keyword args to pass to the LDAP group type class, default `{'name_attr': 'cn'}` | +| `INVENTREE_LDAP_REQUIRE_GROUP` | `ldap.require_group` | If set, users _must_ be in this group to log in to InvenTree | +| `INVENTREE_LDAP_DENY_GROUP` | `ldap.deny_group` | If set, users _must not_ be in this group to log in to InvenTree | +| `INVENTREE_LDAP_USER_FLAGS_BY_GROUP` | `ldap.user_flags_by_group` | LDAP group to InvenTree user flag map, can be json if used as env, in yml directly specify the object. See config template for example, default: `{}` | ## Tracing support Starting with 0.14.0 InvenTree supports sending traces, logs and metrics to OpenTelemetry compatible endpoints (both HTTP and gRPC). A [list of vendors](https://opentelemetry.io/ecosystem/vendors) is available on the project site. This can be used to track usage and performance of the InvenTree backend and connected services like databases, caches and more. -| config key | ENV Variable | Description | -| --- | --- | --- | -| `tracing.enabled` | `INVENTREE_TRACING_ENABLED` | Set this to `True` to enable OpenTelemetry. | -| `tracing.endpoint` | `INVENTREE_TRACING_ENDPOINT` | General endpoint for information (not specific trace/log url) | -| `tracing.headers` | `INVENTREE_TRACING_HEADERS` | HTTP headers that should be send with every request (often used for authentication). Format as a dict. | -| `tracing.auth.basic` | `INVENTREE_TRACING_AUTH_BASIC` | Auth headers that should be send with every requests (will be encoded to b64 and overwrite auth headers) | -| `tracing.is_http` | `INVENTREE_TRACING_IS_HTTP` | Are the endpoints HTTP (True, default) or gRPC (False) | -| `tracing.append_http` | `INVENTREE_TRACING_APPEND_HTTP` | Append default url routes (v1) to `tracing.endpoint` | -| `tracing.console` | `INVENTREE_TRACING_CONSOLE` | Print out all exports (additionally) to the console for debugging. Do not use in production | -| `tracing.resources` | `INVENTREE_TRACING_RESOURCES` | Add additional resources to all exports. This can be used to add custom tags to the traces. Format as a dict. | +{{ configtable() }} +{{ configsetting("INVENTREE_TRACING_ENABLED") }} Enable OpenTelemetry | +{{ configsetting("INVENTREE_TRACING_ENDPOINT") }} General endpoint for information (not specific trace/log url) | +{{ configsetting("INVENTREE_TRACING_HEADERS") }} HTTP headers that should be send with every request (often used for authentication). Format as a dict. | +{{ configsetting("INVENTREE_TRACING_AUTH") }} Auth headers that should be send with every requests (will be encoded to b64 and overwrite auth headers) | +{{ configsetting("INVENTREE_TRACING_IS_HTTP") }} Are the endpoints HTTP (True, default) or gRPC (False) | +{{ configsetting("INVENTREE_TRACING_APPEND_HTTP") }} Append default url routes (v1) to `tracing.endpoint` | +{{ configsetting("INVENTREE_TRACING_CONSOLE") }} Print out all exports (additionally) to the console for debugging. Do not use in production | +{{ configsetting("INVENTREE_TRACING_RESOURCES") }} Add additional resources to all exports. This can be used to add custom tags to the traces. Format as a dict. | ## Multi Site Support @@ -99,7 +97,6 @@ If your InvenTree instance is used in a multi-site environment, you can enable m !!! tip "Django Documentation" For more information on multi-site support, refer to the [Django documentation]({% include "django.html" %}/ref/contrib/sites/). -| Environment Variable | Config Key | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_SITE_MULTI | site_multi | Enable multiple sites | False | -| INVENTREE_SITE_ID | site_id | Specify a fixed site ID | _Not specified_ | +{{ configtable() }} +{{ configsetting("INVENTREE_SITE_MULTI") }} Enable multiple sites | +{{ configsetting("INVENTREE_SITE_ID") }} Specify a fixed site ID | diff --git a/docs/docs/start/backup.md b/docs/docs/start/backup.md index e96cc0088a..fb6ae5f9c9 100644 --- a/docs/docs/start/backup.md +++ b/docs/docs/start/backup.md @@ -17,19 +17,19 @@ The django-dbbackup library provides [multiple configuration options](https://ar The following configuration options are available for backup: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_BACKUP_STORAGE | backup_storage | Backup storage backend. Refer to the [storage backend documentation](#storage-backend). | django.core.files.storage.FileSystemStorage | -| INVENTREE_BACKUP_DIR | backup_dir | Backup storage directory. | *No default* | -| INVENTREE_BACKUP_OPTIONS | backup_options | Specific options for the selected storage backend (dict) | *No default* | -| INVENTREE_BACKUP_CONNECTOR_OPTIONS | backup_connector_options | Specific options for the database connector (dict). Refer to the [database connector options](#database-connector). | *No default* | -| INVENTREE_BACKUP_SEND_EMAIL | backup_send_email | If True, an email is sent to the site admin when an error occurs during a backup or restore procedure. | False | -| INVENTREE_BACKUP_EMAIL_PREFIX | backup_email_prefix | Prefix for the subject line of backup-related emails. | `[InvenTree Backup]` | -| INVENTREE_BACKUP_GPG_RECIPIENT | backup_gpg_recipient | Specify GPG recipient if using encryption for backups. | *No default* | -| INVENTREE_BACKUP_DATE_FORMAT | backup_date_format | Date format string used to format timestamps in backup filenames. | `%Y-%m-%d-%H%M%S` | -| INVENTREE_BACKUP_DATABASE_FILENAME_TEMPLATE | backup_database_filename_template | Template string used to generate database backup filenames. | `InvenTree-db-{datetime}.{extension}` | -| INVENTREE_BACKUP_MEDIA_FILENAME_TEMPLATE | backup_media_filename_template | Template string used to generate media backup filenames. | `InvenTree-media-{datetime}.{extension}` | -| INVENTREE_BACKUP_RESTORE_ALLOW_NEWER_VERSION | backup_restore_allow_newer_version | If True, allows restoring a backup created with a newer version of InvenTree. This is dangerous as it can lead to hard-to-debug data loss. | False | +{{ configtable() }} +{{ configsetting("INVENTREE_BACKUP_STORAGE") }} Backup storage backend. Refer to the [storage backend documentation](#storage-backend). | +{{ configsetting("INVENTREE_BACKUP_DIR") }} Backup storage directory. | +{{ configsetting("INVENTREE_BACKUP_OPTIONS") }} Specific options for the selected storage backend (dict) | +{{ configsetting("INVENTREE_BACKUP_CONNECTOR_OPTIONS") }} Specific options for the database connector (dict). Refer to the [database connector options](#database-connector) | +{{ configsetting("INVENTREE_BACKUP_SEND_EMAIL") }} If True, an email is sent to the site admin when an error occurs during a backup or restore procedure. | +{{ configsetting("INVENTREE_BACKUP_EMAIL_PREFIX") }} Prefix for the subject line of backup-related emails. | +{{ configsetting("INVENTREE_BACKUP_GPG_RECIPIENT") }} Specify GPG recipient if using encryption for backups. | +{{ configsetting("INVENTREE_BACKUP_DATE_FORMAT") }} Date format string used to format timestamps in backup filenames. | +{{ configsetting("INVENTREE_BACKUP_DATABASE_FILENAME_TEMPLATE") }} Template string used to generate database backup filenames. +{{ configsetting("INVENTREE_BACKUP_MEDIA_FILENAME_TEMPLATE") }} Template string used to generate media backup filenames. | +{{ configsetting("INVENTREE_BACKUP_RESTORE_ALLOW_NEWER_VERSION") }} If True, allows restoring a backup created with a newer version of InvenTree. This is dangerous as it can lead to hard-to-debug data loss. | + ### Storage Backend diff --git a/docs/docs/start/config.md b/docs/docs/start/config.md index 5286b2080f..d7b9d18297 100644 --- a/docs/docs/start/config.md +++ b/docs/docs/start/config.md @@ -46,6 +46,9 @@ Environment variable settings generally use the `INVENTREE_` prefix, and are all !!! warning "Available Variables" Some configuration options cannot be set via environment variables. Refer to the documentation below. +!!! info "Environment Variable Priority" + Note that a provided environment variable will override the value provided in the configuration file. + #### List Values To specify a list value in an environment variable, use a comma-separated list. For example, to specify a list of trusted origins: @@ -58,14 +61,13 @@ INVENTREE_TRUSTED_ORIGINS='https://inventree.example.com:8443,https://stock.exam The following basic options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_SITE_URL | site_url | Specify a fixed site URL | *Not specified* | -| INVENTREE_TIMEZONE | timezone | Server timezone | UTC | -| INVENTREE_ADMIN_ENABLED | admin_enabled | Enable the [django administrator interface]({% include "django.html" %}/ref/contrib/admin/) | True | -| INVENTREE_ADMIN_URL | admin_url | URL for accessing [admin interface](../settings/admin.md) | admin | -| INVENTREE_LANGUAGE | language | Default language | en-us | -| INVENTREE_AUTO_UPDATE | auto_update | Database migrations will be run automatically | False | +{{ configtable() }} +{{ 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_LANGUAGE") }} Default language | +{{ configsetting("INVENTREE_AUTO_UPDATE") }} Database migrations will be run automatically | ### Site URL @@ -89,18 +91,17 @@ With "auto update" enabled, the InvenTree server will automatically apply databa The following debugging / logging options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_DEBUG | debug | Enable [debug mode](./index.md#debug-mode) | False | -| INVENTREE_DEBUG_QUERYCOUNT | debug_querycount | Enable support for [django-querycount](../develop/index.md#django-querycount) middleware. | False | -| INVENTREE_DEBUG_SILK | debug_silk | Enable support for [django-silk](../develop/index.md#django-silk) profiling tool. | False | -| INVENTREE_DEBUG_SILK_PROFILING | debug_silk_profiling | Enable detailed profiling in django-silk | False | -| INVENTREE_DB_LOGGING | db_logging | Enable logging of database messages | False | -| INVENTREE_LOG_LEVEL | log_level | Set level of logging to terminal | WARNING | -| INVENTREE_JSON_LOG | json_log | log as json | False | -| INVENTREE_WRITE_LOG | write_log | Enable writing of log messages to file at config base | False | -| INVENTREE_CONSOLE_LOG | console_log | Enable logging to console | True | -| INVENTREE_SCHEMA_LEVEL | schema.level | Set level of added schema extensions detail (0-3) 0 = including no additional detail | 0 | +{{ configtable() }} +{{ configsetting("INVENTREE_DEBUG") }} Enable [debug mode](./index.md#debug-mode) | +{{ configsetting("INVENTREE_DB_LOGGING") }} Enable logging of database messages | +{{ configsetting("INVENTREE_LOG_LEVEL") }} Set level of logging to terminal | +{{ configsetting("INVENTREE_JSON_LOG") }} Log messages as json | +{{ configsetting("INVENTREE_WRITE_LOG") }} Enable writing of log messages to file at config base | +{{ configsetting("INVENTREE_CONSOLE_LOG") }} Enable logging to console | +{{ configsetting("INVENTREE_SCHEMA_LEVEL") }} Set level of added schema extensions detail (0-3) 0 = including no additional detail | +{{ configsetting("INVENTREE_DEBUG_QUERYCOUNT") }} Enable support for [django-querycount](../develop/index.md#django-querycount) middleware. | +{{ configsetting("INVENTREE_DEBUG_SILK") }} Enable support for [django-silk](../develop/index.md#django-silk) profiling tool. | +| `INVENTREE_DEBUG_SILK_PROFILING` | `debug_silk_profiling` | False | Enable detailed profiling in django-silk | ### Debug Mode @@ -118,26 +119,24 @@ Depending on how your InvenTree installation is configured, you will need to pay !!! danger "Not Secure" Allowing access from any host is not secure, and should be adjusted for your installation. -!!! info "Environment Variables" - Note that a provided environment variable will override the value provided in the configuration file. - !!! 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). -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_ALLOWED_HOSTS | allowed_hosts | List of allowed hosts | `*` | -| INVENTREE_TRUSTED_ORIGINS | trusted_origins | List of trusted origins. Refer to the [django documentation]({% include "django.html" %}/ref/settings/#csrf-trusted-origins) | Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list. | -| INVENTREE_CORS_ORIGIN_ALLOW_ALL | cors.allow_all | Allow all remote URLS for CORS checks | `False` | -| INVENTREE_CORS_ORIGIN_WHITELIST | cors.whitelist | List of whitelisted CORS URLs. Refer to the [django-cors-headers documentation](https://github.com/adamchainz/django-cors-headers#cors_allowed_origins-sequencestr) | Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list. | -| INVENTREE_CORS_ORIGIN_REGEX | cors.regex | List of regular expressions for CORS whitelisted URL patterns | *Empty list* | -| INVENTREE_CORS_ALLOW_CREDENTIALS | cors.allow_credentials | Allow cookies in cross-site requests | `True` | -| INVENTREE_SITE_LAX_PROTOCOL | site_lax_protocol | Ignore protocol mismatches on INVE-E7 site checks | `True` | -| INVENTREE_USE_X_FORWARDED_HOST | use_x_forwarded_host | Use forwarded host header | `False` | -| INVENTREE_USE_X_FORWARDED_PORT | use_x_forwarded_port | Use forwarded port header | `False` | -| INVENTREE_USE_X_FORWARDED_PROTO | use_x_forwarded_proto | Use forwarded protocol header | `False` | -| INVENTREE_SESSION_COOKIE_SECURE | cookie.secure | Enforce secure session cookies | `False` | -| INVENTREE_COOKIE_SAMESITE | 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. | False | +{{ 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) | +{{ configsetting("INVENTREE_CORS_ORIGIN_ALLOW_ALL") }} Allow all remote URLS for CORS checks | +{{ configsetting("INVENTREE_CORS_ORIGIN_WHITELIST", default="Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list.") }} List of whitelisted CORS URLs. Refer to the [django-cors-headers documentation](https://github.com/adamchainz/django-cors-headers#cors_allowed_origins-sequencestr) | +{{ configsetting("INVENTREE_CORS_ORIGIN_REGEX") }} List of regular expressions for CORS whitelisted URL patterns | +{{ configsetting("INVENTREE_CORS_ALLOW_CREDENTIALS") }} Allow cookies in cross-site requests | +{{ configsetting("INVENTREE_SITE_LAX_PROTOCOL") }} Ignore protocol mismatches on INVE-E7 site checks | +{{ configsetting("INVENTREE_USE_X_FORWARDED_HOST") }} Use forwarded host header | +{{ configsetting("INVENTREE_USE_X_FORWARDED_PORT") }} Use forwarded port header | +{{ configsetting("INVENTREE_USE_X_FORWARDED_PROTO") }} Use forwarded protocol header | +| `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. | + ### Debug Mode @@ -185,17 +184,15 @@ Proxy configuration can be complex, and any configuration beyond the basic setup Refer to the [proxy server documentation](./processes.md#proxy-server) for more information. - ## Admin Site Django provides a powerful [administrator interface]({% include "django.html" %}/ref/contrib/admin/) which can be used to manage the InvenTree database. This interface is enabled by default, and available at the `/admin/` URL. The following admin site configuration options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_ADMIN_ENABLED | admin_enabled | Enable the django administrator interface | True | -| INVENTREE_ADMIN_URL | admin_url | URL for accessing the admin interface | admin | +{{ configtable() }} +{{ configsetting("INVENTREE_ADMIN_ENABLED") }} Enable the django administrator interface | +{{ configsetting("INVENTREE_ADMIN_URL") }} URL for accessing the admin interface | !!! warning "Security" Changing the admin URL is a simple way to improve security, but it is not a substitute for proper security practices. @@ -204,12 +201,11 @@ The following admin site configuration options are available: An administrator account can be specified using the following environment variables: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_ADMIN_USER | admin_user | Admin account username | *Not specified* | -| INVENTREE_ADMIN_PASSWORD | admin_password | Admin account password | *Not specified* | -| INVENTREE_ADMIN_PASSWORD_FILE | admin_password_file | Admin account password file | *Not specified* | -| INVENTREE_ADMIN_EMAIL | admin_email |Admin account email address | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_ADMIN_USER") }} Admin account username | +{{ configsetting("INVENTREE_ADMIN_PASSWORD") }} Admin account password | +{{ configsetting("INVENTREE_ADMIN_PASSWORD_FILE") }} Admin account password file | +{{ configsetting("INVENTREE_ADMIN_EMAIL") }} Admin account email address | You can either specify the password directly using `INVENTREE_ADMIN_PASSWORD`, or you can specify a file containing the password using `INVENTREE_ADMIN_PASSWORD_FILE` (this is useful for nix users). @@ -239,12 +235,11 @@ A PEM-encoded file containing the oidc private key can be passed via the environ If not specified via environment variables, the fallback files (automatically generated as part of InvenTree installation) will be used. -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_SECRET_KEY | secret_key | Raw secret key value | *Not specified* | -| INVENTREE_SECRET_KEY_FILE | secret_key_file | File containing secret key value | *Not specified* | -| INVENTREE_OIDC_PRIVATE_KEY | oidc_private_key | Raw private key value | *Not specified* | -| INVENTREE_OIDC_PRIVATE_KEY_FILE | oidc_private_key_file | File containing private key value in PEM format | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_SECRET_KEY") }} Raw secret key value | +{{ configsetting("INVENTREE_SECRET_KEY_FILE") }} File containing secret key value | +{{ configsetting("INVENTREE_OIDC_PRIVATE_KEY") }} Raw private key value | +{{ configsetting("INVENTREE_OIDC_PRIVATE_KEY_FILE", default="oidc.pem") }} File containing private key value in PEM format | ## Database Options @@ -254,14 +249,14 @@ Database options are specified under the *database* heading in the configuration The following database options can be configured: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_DB_ENGINE | database.ENGINE | Database backend | *Not specified* | -| INVENTREE_DB_NAME | database.NAME | Database name | *Not specified* | -| INVENTREE_DB_USER | database.USER | Database username (if required) | *Not specified* | -| INVENTREE_DB_PASSWORD | database.PASSWORD | Database password (if required) | *Not specified* | -| INVENTREE_DB_HOST | database.HOST | Database host address (if required) | *Not specified* | -| INVENTREE_DB_PORT | database.PORT | Database host port (if required) | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_DB_ENGINE") }} Database backend | +{{ configsetting("INVENTREE_DB_NAME") }} Database name | +{{ configsetting("INVENTREE_DB_USER") }} Database username (if required) | +{{ 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_OPTIONS") }} Additional database options (as a JSON object) | !!! tip "Database Password" The value specified for `INVENTREE_DB_PASSWORD` should not contain comma `,` or colon `:` characters, otherwise the connection to the database may fail. @@ -270,22 +265,31 @@ The following database options can be configured: If running with a PostgreSQL database backend, the following additional options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_DB_TIMEOUT | database.timeout | Database connection timeout (s) | 2 | -| INVENTREE_DB_TCP_KEEPALIVES | database.tcp_keepalives | TCP keepalive | 1 | -| INVENTREE_DB_TCP_KEEPALIVES_IDLE | database.tcp_keepalives_idle | Idle TCP keepalive | 1 | -| INVENTREE_DB_TCP_KEEPALIVES_INTERNAL | database.tcp_keepalives_internal | Internal TCP keepalive | 1| -| INVENTREE_DB_TCP_KEEPALIVES_COUNT | database.tcp_keepalives_count | TCP keepalive count | 5 | -| INVENTREE_DB_ISOLATION_SERIALIZABLE | database.serializable | Database isolation level configured to "serializable" | False | +{{ configtable() }} +{{ configsetting("INVENTREE_DB_TIMEOUT", default="2") }} 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_COUNT` | database.tcp_keepalives_count | 5 | TCP keepalive count | +| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" | ### MySQL Settings If running with a MySQL database backend, the following additional options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_DB_ISOLATION_SERIALIZABLE | database.serializable | Database isolation level configured to "serializable" | False | +{{ configtable() }} +| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" | + +### SQLite Settings + +!!! warning "SQLite Performance" + SQLite is not recommended for production use, and should only be used for testing or development purposes. If you are using SQLite in production, you may want to adjust the following settings to improve performance. + +If running with a SQLite database backend, the following additional options are available: + +{{ configtable() }} +{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) | +| `INVENTREE_DB_WAL_MODE` | database.wal_mode | True | Enable Write-Ahead Logging (WAL) mode for SQLite databases | ## Caching @@ -303,20 +307,21 @@ Enabling global caching requires connection to a redis server (which is separate The following cache settings are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_CACHE_ENABLED | cache.enabled | Enable redis caching | False | -| INVENTREE_CACHE_HOST | cache.host | Cache server host | *Not specified* | -| INVENTREE_CACHE_PORT | cache.port | Cache server port | 6379 | -| INVENTREE_CACHE_PASSWORD | cache.password | Cache server password | none | -| INVENTREE_CACHE_USER | cache.user | Cache server username | none | -| INVENTREE_CACHE_CONNECT_TIMEOUT | cache.connect_timeout | Cache connection timeout (seconds) | 3 | -| INVENTREE_CACHE_TIMEOUT | cache.timeout | Cache timeout (seconds) | 3 | -| INVENTREE_CACHE_TCP_KEEPALIVE | cache.tcp_keepalive | Cache TCP keepalive | True | -| INVENTREE_CACHE_KEEPALIVE_COUNT | cache.keepalive_count | Cache keepalive count | 5 | -| INVENTREE_CACHE_KEEPALIVE_IDLE | cache.keepalive_idle | Cache keepalive idle | 1 | -| INVENTREE_CACHE_KEEPALIVE_INTERVAL | cache.keepalive_interval | Cache keepalive interval | 1 | -| INVENTREE_CACHE_USER_TIMEOUT | cache.user_timeout | Cache user timeout | 1000 | +{{ configtable() }} +{{ configsetting("INVENTREE_CACHE_ENABLED") }} Enable redis caching | +{{ configsetting("INVENTREE_CACHE_HOST") }} Cache server host | +{{ configsetting("INVENTREE_CACHE_PORT") }} Cache server port | +{{ configsetting("INVENTREE_CACHE_PASSWORD") }} Cache server password | +{{ configsetting("INVENTREE_CACHE_USER") }} Cache server username | +{{ configsetting("INVENTREE_CACHE_DB") }} Cache server database index | +{{ configsetting("INVENTREE_CACHE_CONNECT_TIMEOUT") }} Cache connection timeout (seconds) | +{{ configsetting("INVENTREE_CACHE_TIMEOUT") }} Cache timeout (seconds) | +{{ configsetting("INVENTREE_CACHE_TCP_KEEPALIVE") }} Cache TCP keepalive | +{{ configsetting("INVENTREE_CACHE_KEEPALIVE_COUNT") }} Cache keepalive count | +{{ configsetting("INVENTREE_CACHE_KEEPALIVE_IDLE") }} Cache keepalive idle | +{{ configsetting("INVENTREE_CACHE_KEEPALIVE_INTERVAL") }} Cache keepalive interval | +{{ configsetting("INVENTREE_CACHE_USER_TIMEOUT") }} Cache user timeout | + !!! tip "Cache Password" The value specified for `INVENTREE_CACHE_PASSWORD` should not contain comma `,` or colon `:` characters, otherwise the connection to the cache server may fail. @@ -327,17 +332,16 @@ To enable [email functionality](../settings/email.md), email settings must be co The following email settings are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_EMAIL_BACKEND | email.backend | Email backend module | django.core.mail.backends.smtp.EmailBackend | -| INVENTREE_EMAIL_HOST | email.host | Email server host | *Not specified* | -| INVENTREE_EMAIL_PORT | email.port | Email server port | 25 | -| INVENTREE_EMAIL_USERNAME | email.username | Email account username | *Not specified* | -| INVENTREE_EMAIL_PASSWORD | email.password | Email account password | *Not specified* | -| INVENTREE_EMAIL_TLS | email.tls | Enable STARTTLS support (commonly port 567) | False | -| INVENTREE_EMAIL_SSL | email.ssl | Enable legacy SSL/TLS support (commonly port 465) | False | -| INVENTREE_EMAIL_SENDER | email.sender | Sending email address | *Not specified* | -| INVENTREE_EMAIL_PREFIX | email.prefix | Prefix for subject text | [InvenTree] | +{{ configtable() }} +{{ configsetting("INVENTREE_EMAIL_BACKEND") }} Email backend module | +{{ configsetting("INVENTREE_EMAIL_HOST") }} Email server host | +{{ configsetting("INVENTREE_EMAIL_PORT") }} Email server port | +{{ configsetting("INVENTREE_EMAIL_USERNAME") }} Email account username | +{{ configsetting("INVENTREE_EMAIL_PASSWORD") }} Email account password | +{{ configsetting("INVENTREE_EMAIL_TLS") }} Enable STARTTLS support (commonly port 567) | +{{ configsetting("INVENTREE_EMAIL_SSL") }} Enable legacy SSL/TLS support (commonly port 465) | +{{ configsetting("INVENTREE_EMAIL_SENDER") }} Sending email address | +{{ configsetting("INVENTREE_EMAIL_PREFIX") }} Prefix for subject text | ### Email Backend @@ -354,11 +358,10 @@ The "sender" email address is the address from which InvenTree emails are sent ( InvenTree requires some external directories for storing files: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_STATIC_ROOT | static_root | [Static files](./processes.md#static-files) directory | *Not specified* | -| INVENTREE_MEDIA_ROOT | media_root | [Media files](./processes.md#media-files) directory | *Not specified* | -| INVENTREE_BACKUP_DIR | backup_dir | Backup files directory | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_STATIC_ROOT") }} [Static files](./processes.md#static-files) directory | +{{ configsetting("INVENTREE_MEDIA_ROOT") }} [Media files](./processes.md#media-files) directory | +{{ configsetting("INVENTREE_BACKUP_DIR") }} Directory for backup files | !!! tip "Serving Files" Read the [proxy server documentation](./processes.md#proxy-server) for more information on hosting *static* and *media* files @@ -392,47 +395,41 @@ Alternatively this location can be specified with the `INVENTREE_BACKUP_DIR` env It is also possible to use alternative storage backends for static and media files, at the moment there is direct provide direct support bundled for S3 and SFTP. Google cloud storage and Azure blob storage would also be supported by the [used library](https://django-storages.readthedocs.io), but require additional packages to be installed. -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_STORAGE_TARGET | storage.target | Storage target to use for static and media files, valid options: local, s3, sftp | local | +{{ configtable() }} +{{ configsetting("INVENTREE_STORAGE_TARGET") }} Storage target to use for static and media files, valid options: local, s3, sftp | + #### S3 -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_S3_ACCESS_KEY | storage.s3.access_key | Access key | *Not specified* | -| INVENTREE_S3_SECRET_KEY | storage.s3.secret_key | Secret key | -| *Not specified* | -| INVENTREE_S3_BUCKET_NAME | storage.s3.bucket_name | Bucket name, required by most providers | -| *Not specified* | -| INVENTREE_S3_REGION_NAME | storage.s3.region_name | S3 region name | -| *Not specified* | -| INVENTREE_S3_ENDPOINT_URL | storage.s3.endpoint_url | Custom S3 endpoint URL, defaults to AWS endpoints if not set | -| *Not specified* | -| INVENTREE_S3_LOCATION | storage.s3.location | Sub-Location that should be used | inventree-server | -| INVENTREE_S3_DEFAULT_ACL | storage.s3.default_acl | Default ACL for uploaded files, defaults to provider default if not set | *Not specified* | -| INVENTREE_S3_VERIFY_SSL | storage.s3.verify_ssl | Verify SSL certificate for S3 endpoint | True | -| INVENTREE_S3_OVERWRITE | storage.s3.overwrite | Overwrite existing files in S3 bucket | False | -| INVENTREE_S3_VIRTUAL | storage.s3.virtual | Use virtual addressing style - by default False -> `path` style, `virtual` style if True | False | +{{ configtable() }} +| `INVENTREE_S3_ACCESS_KEY` | storage.s3.access_key | *Not specified* | Access key | +| `INVENTREE_S3_SECRET_KEY` | storage.s3.secret_key | *Not specified* | Secret key | +| `INVENTREE_S3_BUCKET_NAME` | storage.s3.bucket_name | *Not specified* | Bucket name, required by most providers | +| `INVENTREE_S3_REGION_NAME` | storage.s3.region_name | *Not specified* | S3 region name | +| `INVENTREE_S3_ENDPOINT_URL` | storage.s3.endpoint_url | *Not specified* | Custom S3 endpoint URL, defaults to AWS endpoints if not set | +| `INVENTREE_S3_LOCATION` | storage.s3.location | inventree-server | Sub-Location that should be used | +| `INVENTREE_S3_DEFAULT_ACL` | storage.s3.default_acl | *Not specified* | Default ACL for uploaded files, defaults to provider default if not set | +| `INVENTREE_S3_VERIFY_SSL` | storage.s3.verify_ssl | True | Verify SSL certificate for S3 endpoint | +| `INVENTREE_S3_OVERWRITE` | storage.s3.overwrite | False | Overwrite existing files in S3 bucket | +| `INVENTREE_S3_VIRTUAL` | storage.s3.virtual | False | Use virtual addressing style - by default False -> `path` style, `virtual` style if True | #### SFTP -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_SFTP_HOST | storage.sftp.host | SFTP host | *Not specified* | -| INVENTREE_SFTP_PARAMS | storage.sftp.params | SFTP connection parameters, see https://docs.paramiko.org/en/latest/api/client.html#paramiko.client.SSHClient.connect; e.g. `{'port': 22, 'user': 'usr', 'password': 'pwd'}` | *Not specified* | -| INVENTREE_SFTP_UID | storage.sftp.uid | SFTP user ID - not required | *Not specified* | -| INVENTREE_SFTP_GID | storage.sftp.gid | SFTP group ID - not required | *Not specified* | -| INVENTREE_SFTP_LOCATION | storage.sftp.location | Sub-Location that should be used | inventree-server | +{{ configtable() }} +| `INVENTREE_SFTP_HOST` | storage.sftp.host | *Not specified* | SFTP host | +| `INVENTREE_SFTP_PARAMS` | storage.sftp.params | *Not specified* | SFTP connection parameters, see https://docs.paramiko.org/en/latest/api/client.html#paramiko.client.SSHClient.connect; e.g. `{'port': 22, 'user': 'usr', 'password': 'pwd'}` | +| `INVENTREE_SFTP_UID` | storage.sftp.uid | *Not specified* | SFTP user ID - not required | +| `INVENTREE_SFTP_GID` | storage.sftp.gid | *Not specified* | SFTP group ID - not required | +| `INVENTREE_SFTP_LOCATION` | storage.sftp.location | inventree-server | Sub-Location that should be used | ## Authentication InvenTree provides allowance for additional sign-in options. The following options are not enabled by default, and care must be taken by the system administrator when configuring these settings. -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_MFA_ENABLED | mfa_enabled | Enable or disable multi-factor authentication support for the InvenTree server | True | -| INVENTREE_MFA_SUPPORTED_TYPES | mfa_supported_types | List of supported multi-factor authentication types | recovery_codes,totp,webauthn | +{{ configtable() }} +{{ configsetting("INVENTREE_MFA_ENABLED") }} Enable multi-factor authentication support for the InvenTree server | +{{ configsetting("INVENTREE_MFA_SUPPORTED_TYPES") }} List of supported multi-factor authentication types | +{{ configsetting("INVENTREE_USE_JWT") }} Enable support for JSON Web Tokens (JWT) for authentication | ### Single Sign On @@ -447,11 +444,10 @@ There are multiple configuration parameters which must be specified (either in y The login-experience can be altered with the following settings: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_LOGIN_CONFIRM_DAYS | login_confirm_days | Duration for which confirmation links are valid | 3 | -| INVENTREE_LOGIN_ATTEMPTS | login_attempts | Count of allowed login attempts before blocking user | 5 | -| INVENTREE_LOGIN_DEFAULT_HTTP_PROTOCOL | login_default_protocol | Default protocol to use for login callbacks (e.g. using [SSO](#single-sign-on)) | Uses the protocol specified in `INVENTREE_SITE_URL`, or defaults to *http* | +{{ configtable() }} +{{ configsetting("INVENTREE_LOGIN_CONFIRM_DAYS") }} Duration for which confirmation links are valid | +{{ configsetting("INVENTREE_LOGIN_ATTEMPTS") }} Count of allowed login attempts before blocking user | +{{ configsetting("INVENTREE_LOGIN_DEFAULT_HTTP_PROTOCOL", default="Uses the protocol specified in `INVENTREE_SITE_URL`, or defaults to *http*") }} Default protocol to use for login callbacks (e.g. using [SSO](#single-sign-on)) | !!! tip "Default Protocol" If you have specified `INVENTREE_SITE_URL`, the default protocol will be used from that setting. Otherwise, the default protocol will be *http*. @@ -460,15 +456,24 @@ The login-experience can be altered with the following settings: Custom authentication backends can be used by specifying them here. These can for example be used to add [LDAP / AD login](https://django-auth-ldap.readthedocs.io/en/latest/) to InvenTree +## Background Worker Options + +The following options are available for configuring the InvenTree [background worker process](./processes.md#background-worker): + +{{ configtable() }} +{{ configsetting("INVENTREE_BACKGROUND_WORKERS") }} Number of background worker processes | +{{ configsetting("INVENTREE_BACKGROUND_TIMEOUT") }} Timeout for background worker tasks (seconds) | +{{ configsetting("INVENTREE_BACKGROUND_RETRY") }} Time to wait before retrying a background task (seconds) | +{{ configsetting("INVENTREE_BACKGROUND_MAX_ATTEMPTS") }} Maximum number of attempts for a background task | + ## Sentry Integration The InvenTree server can be integrated with the [sentry.io](https://sentry.io) monitoring service, for error logging and performance tracking. -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_SENTRY_ENABLED | sentry_enabled | Enable sentry.io integration | False | -| INVENTREE_SENTRY_DSN | sentry_dsn | Sentry DSN (data source name) key | *Defaults to InvenTree developer key* | -| INVENTREE_SENTRY_SAMPLE_RATE | sentry_sample_rate | How often to send data samples | 0.1 | +{{ configtable() }} +{{ configsetting("INVENTREE_SENTRY_ENABLED") }} Enable sentry.io integration | +{{ configsetting("INVENTREE_SENTRY_DSN", default="Defaults to InvenTree developer key") }} Sentry DSN (data source name) key | +{{ configsetting("INVENTREE_SENTRY_SAMPLE_RATE") }} How often to send data samples (seconds) | !!! info "Default DSN" If enabled with the default DSN, server errors will be logged to a sentry.io account monitored by the InvenTree developers. @@ -477,13 +482,11 @@ The InvenTree server can be integrated with the [sentry.io](https://sentry.io) m The logo and custom messages can be changed/set: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_CUSTOM_LOGO | customize.logo | Path to custom logo in the static files directory | *Not specified* | -| INVENTREE_CUSTOM_SPLASH | customize.splash | Path to custom splash screen in the static files directory | *Not specified* | -| INVENTREE_CUSTOMIZE | customize.site_header | Custom site header in the Django admin | InvenTree Admin | -| INVENTREE_CUSTOMIZE | customize.login_message | Custom message for login page | *Not specified* | -| INVENTREE_CUSTOMIZE | customize.navbar_message | Custom message for navbar | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_CUSTOM_LOGO") }} Path to custom logo in the static files directory | +{{ configsetting("INVENTREE_CUSTOM_SPLASH") }} Path to custom splash screen in the static files directory | +{{ configsetting("INVENTREE_SITE_HEADER") }} Custom header text for the django admin page | +{{ configsetting("INVENTREE_CUSTOMIZE") }} JSON object containing custom messages for the login page, navbar, and Django admin site | The INVENTREE_CUSTOMIZE environment variable must contain a json object with the keys from the table above and the wanted values. Example: @@ -527,15 +530,15 @@ INVENTREE_FRONTEND_SETTINGS='{"mobile_mode": "allow-ignore"}' The following [plugin](../plugins/index.md) configuration options are available: -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| INVENTREE_PLUGINS_ENABLED | plugins_enabled | Enable plugin support | False | -| INVENTREE_PLUGIN_NOINSTALL | plugin_noinstall | Disable Plugin installation via API - only use plugins.txt file | False | -| INVENTREE_PLUGIN_FILE | plugins_plugin_file | Location of plugin installation file | *Not specified* | -| INVENTREE_PLUGIN_DIR | plugins_plugin_dir | Location of external plugin directory | *Not specified* | -| INVENTREE_PLUGINS_MANDATORY | plugins_mandatory | List of [plugins which are considered mandatory](../plugins/index.md#mandatory-third-party-plugins) | *Not specified* | -| INVENTREE_PLUGIN_DEV_SLUG | plugin_dev.slug | Specify plugin to run in [development mode](../plugins/creator.md#backend-configuration) | *Not specified* | -| INVENTREE_PLUGIN_DEV_HOST | plugin_dev.host | Specify host for development mode plugin | http://localhost:5174 | +{{ configtable() }} +{{ configsetting("INVENTREE_PLUGINS_ENABLED") }} Enable plugin support | +{{ configsetting("INVENTREE_PLUGIN_NOINSTALL") }} Disable Plugin installation via API | +{{ configsetting("INVENTREE_PLUGIN_FILE") }} Location of plugin installation file | +| `INVENTREE_PLUGIN_DIR` | `plugin_dir` | *Not specified* | Location of external plugin directory | +{{ configsetting("INVENTREE_PLUGIN_RETRY") }} Number of tries to attempt loading a plugin before giving up | +{{ configsetting("INVENTREE_PLUGINS_MANDATORY") }} List of [plugins which are considered mandatory](../plugins/index.md#mandatory-third-party-plugins) | +{{ configsetting("INVENTREE_PLUGIN_DEV_SLUG") }} Specify plugin to run in [development mode](../plugins/creator.md#backend-configuration) | +{{ configsetting("INVENTREE_PLUGIN_DEV_HOST") }} Specify host for development mode plugin | ## Override Global Settings @@ -543,6 +546,12 @@ If required, [global settings values](../settings/global.md#override-global-sett To override global settings, provide a "dictionary" of settings overrides in the configuration file, or via an environment variable. -| Environment Variable | Configuration File | Description | Default | -| --- | --- | --- | --- | -| GLOBAL_SETTINGS_OVERRIDES | global_settings_overrides | JSON object containing global settings overrides | *Not specified* | +{{ configtable() }} +{{ configsetting("INVENTREE_GLOBAL_SETTINGS") }} JSON object containing global settings overrides | + +## Other Settings + +Other available settings, not categorized above, are detailed in the table below: + +{{ configtable() }} +{{ configsetting("INVENTREE_EXTRA_URL_SCHEMES") }} Allow additional URL schemes for URL validation | diff --git a/docs/docs/start/docker_install.md b/docs/docs/start/docker_install.md index cb4f29da35..44f60ffba1 100644 --- a/docs/docs/start/docker_install.md +++ b/docs/docs/start/docker_install.md @@ -87,13 +87,7 @@ If you are creating the initial database, you need to create an admin (superuser docker compose run inventree-server invoke superuser ``` -Alternatively, admin account details can be specified in the `.env` file, removing the need for this manual step: - -| Variable | Description | -| --- | --- | -| INVENTREE_ADMIN_USER | Admin account username | -| INVENTREE_ADMIN_PASSWORD | Admin account password | -| INVENTREE_ADMIN_EMAIL | Admin account email address | +Alternatively, admin account details can be specified using environment variables, or in the `.env` file, removing the need for this manual step. Refer to the [configuration documentation](./config.md#administrator-account) for more information. !!! warning "Scrub Account Data" Ensure that the admin account credentials are removed from the `.env` file after the first run, for security. @@ -241,9 +235,9 @@ By default, the Dockerized InvenTree web server binds to all available network i This can be adjusted using the following environment variables: | Environment Variable | Default | -| --- | --- | --- | --- | -| INVENTREE_WEB_ADDR | 0.0.0.0 | -| INVENTREE_WEB_PORT | 8000 | +| --- | --- | +| `INVENTREE_WEB_ADDR` | 0.0.0.0 | +| `INVENTREE_WEB_PORT` | 8000 | These variables are combined in the [Dockerfile]({{ sourcefile("contrib/container/Dockerfile") }}) to build the bind string passed to the InvenTree server on startup. diff --git a/docs/docs/start/installer.md b/docs/docs/start/installer.md index 562b2bd936..55f367bc90 100644 --- a/docs/docs/start/installer.md +++ b/docs/docs/start/installer.md @@ -3,9 +3,15 @@ title: InvenTree Installer --- ## Installer + The InvenTree installer automates the installation procedure for a production InvenTree server. -Supported OSs are Debian 10, 11, 12 and Ubuntu 20.04 LTS, 22.04 LTS, 24.04 LTS. +The installer supports the following Linux distributions: + +- Debian 11, 12 +- Ubuntu 22.04 LTS, 24.04 LTS + +Support for other OS versions is not currently planned. If you are using a different distribution, you can still follow the [docker](./docker.md) or [bare metal](./install.md) installation instructions. ### Quick Script @@ -118,6 +124,9 @@ Extra python packages can be installed by setting the environment variable `SETU The used database backend can be configured with environment variables (before the first setup) or in the config file after the installation. Check the [configuration section](./config.md#database-options) for more information. +!!! warning "SQLite Performance" + SQLite is not recommended for production use, as it is not designed for high concurrency. + ## Moving Data To change the data storage location, link the new location to `/opt/inventree/data`. A rough outline of steps to achieve this could be: diff --git a/docs/docs/start/migrate.md b/docs/docs/start/migrate.md index 7eff14a5a1..808ce776bc 100644 --- a/docs/docs/start/migrate.md +++ b/docs/docs/start/migrate.md @@ -67,6 +67,10 @@ invoke import-records -c -f data.json !!! warning "Character Encoding" If the character encoding of the data file does not exactly match the target database, the import operation may not succeed. In this case, some manual editing of the database JSON file may be required. +``` +{{ invoke_commands('import-records --help') }} +``` + ### Copy Media Files Any media files (images, documents, etc) that were stored in the original database must be copied to the new database. In a typical InvenTree installation, these files are stored in the `media` subdirectory of the InvenTree data location. @@ -197,3 +201,32 @@ This will load the database records from the backup file into the new database. ### Caveats The process described here is a *suggested* procedure for migrating between incompatible database versions. However, due to the complexity of database software, there may be unforeseen complications that arise during the process. + +## Migrating Plugin Data + +Custom plugins may define their own database models, and thus have their own data records stored in the database. If a plugin is being migrated from one InvenTree installation to another, then the plugin data must also be migrated. + +To account for this, the `export-records` and `import-records` commands have been designed to also export and import plugin data, in addition to the core InvenTree data. + +### Exporting Plugin Data + +When running the `export-records` command, any data records associated with plugins will also be exported, and included in the output JSON file. + +### Importing Plugin Data + +When running the `import-records` command, the import process will also attempt to import any plugin data records contained in the input JSON file. However, for the plugin data to be imported correctly, the following conditions must be met: + +1. The plugin *code* must be present in the new InvenTree installation. Any plugins *not* installed will not have their tables created, and thus the import process will fail for those records. +2. The plugin *version* must be the same in both installations. If the plugin version is different, then the database schema may be different, and thus the import process may fail. +3. The InvenTree software version must be the same in both installations. If the InvenTree version is different, then the database schema may be different, and thus the import process may fail. + +If all of the above conditions are met, then the plugin data *should* be imported correctly into the new database. To achieve this reliably, the following process steps are implemented in the `import-records` command: + +1. The database is cleaned of all existing records (if the `-c` option is used). +2. The core InvenTree database migrations are run to ensure that the core database schema is correct. +3. User auth records are imported into the database +4. Common configuration records (such as global settings) are imported into the database +5. Plugin configuration records (defining which plugins are active) are imported into the database +6. Database migrations are run once more, to ensure that any plugin database schema are correctly initialized +7. The database is checked to ensure that all required apps are present (i.e. all plugins are installed and correctly activated) +8. All remaining records (including plugin data) are imported into the database diff --git a/docs/docs/start/processes.md b/docs/docs/start/processes.md index 06bea14454..591e0b407c 100644 --- a/docs/docs/start/processes.md +++ b/docs/docs/start/processes.md @@ -16,7 +16,22 @@ InvenTree supports a [number of database backends]({% include "django.html" %}/r Refer to the [database configuration guide](./config.md#database-options) for more information on selecting and configuring the database backend. -In running InvenTree via [docker compose](./docker_install.md), the database process is managed by the `inventree-db` service which provides a [Postgres docker container](https://hub.docker.com/_/postgres). +If running InvenTree via [docker compose](./docker_install.md), the database process is managed by the `inventree-db` service which provides a [Postgres docker container](https://hub.docker.com/_/postgres). + +!!! tip "Postgres Recommended" + We recommend using Postgres as the database backend for InvenTree, as it is a robust and scalable database which is well-suited to production use. + +#### SQLite Limitations + +!!! warning "SQLite Performance" + SQLite is not recommended for production use, as it is not designed for high concurrency. + +While SQLite is supported, it is strongly *not* recommended for a production installation, especially where there may be multiple users accessing the system concurrently. SQLite is designed for low-concurrency applications, and can experience performance issues when multiple users are accessing the database at the same time. + +In addition to concurrency issues, there are other structural limitations which exist in SQLite that can prevent operations on large querysets. + +If you are using SQLite, you should be aware of these limitations. It is important to ensure that the database file is stored on a fast storage medium (such as an SSD), and that the database options are configured correctly to minimize locking issues. Refer to the [database configuration guide](./config.md#database-options) for more information on configuring SQLite options. + ### Web Server @@ -112,6 +127,8 @@ If the background worker process is not running, InvenTree will not be able to p If the [cache server](#cache-server) is not running, the background worker will be limited to running a single threaded worker. This is because the background worker uses the cache server to manage task locking, and without a global cache server to communicate between processes, concurrency issues can occur. +Additionally, if you are running SQLite as the database backend, the background worker will be limited to a single thread, due to database locking issues which can occur with SQLite when multiple threads are accessing the database concurrently. + ### Cache Server The InvenTree cache server is used to store temporary data which is shared between the InvenTree web server and the background worker processes. The cache server is also used to store task information, and to manage task locking between the background worker processes. @@ -126,3 +143,7 @@ InvenTree uses the [Redis](https://redis.io/) cache server to manage cache data. !!! tip "Enable Cache" While a redis container is provided in the default configuration, by default it is not enabled in the InvenTree server. You can enable redis cache support by following the [caching configuration guide](./config.md#caching) + +### Configuration + +Refer to the [background worker configuration options](./config.md#background-worker-options) for more information on configuring the background worker process. diff --git a/docs/docs/stock/index.md b/docs/docs/stock/index.md index 378a53e072..6071e16e0e 100644 --- a/docs/docs/stock/index.md +++ b/docs/docs/stock/index.md @@ -24,7 +24,7 @@ Each *Stock Item* is linked to the following information: **Last Updated** - Date that the stock quantity was last updated -**Last Stocktake** - Date of most recent stocktake (count) of this item +**Last Stocktake** - Date that this stock item was last counted **Status** - Status of this stock item diff --git a/docs/docs/stock/traceability.md b/docs/docs/stock/traceability.md index 5fb21aa608..666cc84de1 100644 --- a/docs/docs/stock/traceability.md +++ b/docs/docs/stock/traceability.md @@ -142,6 +142,8 @@ Note that any serial number adjustments are subject to the same validation rules {{ image("stock/serial_edit_error.png", title="Error while editing a serial number") }} +!!! info "Disable Serial Number Editing" + If you wish to prevent users from editing serial numbers, this can be achieved by disabling the `Allow Edit Serial Number` setting in the system settings view. #### Plugin Support diff --git a/docs/docs/stock/transfer_order.md b/docs/docs/stock/transfer_order.md new file mode 100644 index 0000000000..12381255e5 --- /dev/null +++ b/docs/docs/stock/transfer_order.md @@ -0,0 +1,150 @@ + +--- +title: Transfer Orders +--- + +## Transfer Orders + +Transfer orders provide a method for requesting stock to be moved from one location to another. It does not replace the existing on-demand stock transaction options, but lets you "document" many transactions from a single view. + +### View Transfer Orders + +To navigate to the Transfer Order display, select *Stock* from the main navigation menu, and *Transfer Orders* from the sidebar: + +{{ image("stock/transfer_order_display.png", "Transfer Order display") }} + +The following view modes are available: + +#### Table View + +*Table View* provides a list of Transfer Orders, which can be filtered to display a subset of orders according to user supplied parameters. + +{{ image("stock/transfer_order_list.png", "Transfer Order list") }} + +#### Calendar View + +*Calendar View* shows a calendar display with outstanding transfer orders. + +{{ image("stock/transfer_order_calendar.png", "Transfer Order calendar") }} + +### Transfer Order Status Codes + +Each Transfer Order has a specific status code, which represents the state of the order: + +| Status | Description | +| --- | --- | +| Pending | The transfer order has been created, but has not been finalized or submitted | +| Issued | The transfer order has been issued, and is in progress | +| On Hold | The transfer order has been placed on hold, but is still active | +| Complete | The transfer order is fully completed, and is now closed | +| Cancelled | The transfer order was cancelled, and is now closed | + +**Source Code** + +Refer to the source code for the Transfer Order status codes: + +::: order.status_codes.TransferOrderStatus + options: + show_bases: False + show_root_heading: False + show_root_toc_entry: False + show_source: True + members: [] + +Transfer Order Status supports [custom states](../concepts/custom_states.md). + +### Transfer Order Parameters + +The following parameters are available for each Transfer Order, and can be edited by the user: + +| Parameter | Description | +| --- | --- | +| Reference | Transfer Order reference e.g. '001' | +| Description | Description of the Transfer Order | +| Project Code | Project Code of the Transfer Order | +| Source Location | Stock location to source stock items from (blank = all locations) | +| Destination Location | Stock location where the stock will be transferred | +| Consume Stock | Rather than transfer the stock to the destination, "consume" it by removing the specified quantity from the allocated stock item +| Start Date | The scheduled start date for the transfer | +| Target Date | Target date for transfer completion | +| External Link | Link to external webpage | +| Responsible | User (or group of users) who is responsible for the transfer | +| Notes | Transfer notes, supports markdown | + +## Create a Transfer Order + +Once the transfer order page is loaded, click on {{ icon("plus-circle") }} New Transfer Order which opens the "Create Transfer Order" form. + +Fill out the rest of the form with the transfer order information then click on Submit to create the order. + +### Transfer Order Reference + +Each Transfer Order is uniquely identified by its *Reference* field. Read more about [reference fields](../settings/reference.md). + +### Add Line Items + +On the transfer order detail page, user can link parts to the transfer order selecting the {{ icon("list") }} Line Items tab then clicking on the {{ icon("plus-circle") }} Add Line Item button. + +Once the "Add Line Item" form opens, select a part in the list. + +!!! warning + Only parts that have the "Virtual" attribute disabled will be shown and can be selected. + +Fill out the rest of the form then click on Submit + +### Allocate Stock Items + +After line items were created, user can either: + +* Allocate stock items for that part to the transfer order (click on {{ icon("arrow-right") }} button) +* Create a build order for that part to cover the quantity of the transfer order (click on {{ icon("tools") }} button) + +### Complete Order + +Once all items in the transfer order have been allocated, click on {{ icon("circle-check", color="green") }} Complete Order to mark the transfer order as complete. Confirm then click on Submit to complete the order. + +### Transferred Stock + +After completing the transfer order, a {{ icon("list") }} Transferred Stock tab will appear showing which stock was affected. + +!!! warning + Similar to received stock on purchase orders, this tab will only be accurate while the affected stock items still exist. Furthermore, if the stock item is depleted while using the "consume" parameter, it will not appear here unless "delete on deplete" is turned off for this stock item + +### Cancel Order + +To cancel the order, click on the {{ icon("tools") }} menu button next to the {{ icon("circle-check", color="green") }} Complete Order button, then click on the "{{ icon("tools") }} Cancel Order" menu option. Confirm then click on the Submit to cancel the order. + +## Order Scheduling + +Transfer orders can be scheduled for a future date, to allow for order scheduling. + +### Start Date + +The *Start Date* of the transfer order is the date on which the order is scheduled to be issued, allowing work to begin on the order. + +### Target Date + +The *Target Date* of the transfer order is the date on which the order is scheduled to be completed. + +### Overdue Orders + +If the *Target Date* of the transfer order has passed, the order will be marked as *overdue*. + +## Calendar view + +Using the button to the top right of the list of Transfer Orders, the view can be switched to a calendar view using the button {{ icon("calendar") }}. This view shows orders with a defined target date only. + +This view can be accessed externally as an ICS calendar using a URL like the following: +`http://inventree.example.org/api/order/calendar/transfer-order/calendar.ics` + +By default, completed orders are not exported. These can be included by appending `?include_completed=True` to the URL. + +## Transfer Order Settings + +The following [global settings](../settings/global.md) are available for transfer orders: + +| Name | Description | Default | Units | +| ---- | ----------- | ------- | ----- | +{{ globalsetting("TRANSFERORDER_ENABLED") }} +{{ globalsetting("TRANSFERORDER_REFERENCE_PATTERN") }} +{{ globalsetting("TRANSFERORDER_REQUIRE_RESPONSIBLE") }} diff --git a/docs/main.py b/docs/main.py index c3d8cba512..148e61be65 100644 --- a/docs/main.py +++ b/docs/main.py @@ -34,6 +34,7 @@ for key in [ print(f' - {key}: {val}') # Cached settings dict values +global CONFIG_SETTINGS global GLOBAL_SETTINGS global USER_SETTINGS global TAGS @@ -64,6 +65,7 @@ with open(settings_file, encoding='utf-8') as sf: GLOBAL_SETTINGS = settings['global'] USER_SETTINGS = settings['user'] + CONFIG_SETTINGS = settings['config'] # Tags with open(gen_base.joinpath('inventree_tags.yml'), encoding='utf-8') as f: @@ -377,6 +379,34 @@ def define_env(env): return rendersetting(key, setting, short=short) + @env.macro + def configtable(): + """Generate a header for the configuration settings table.""" + return '| Environment Variable | Configuration File | Default | Description |\n| --- | --- | --- | --- |' + + @env.macro + def configsetting(key: str, default: Optional[str] = None): + """Extract information on a particular configuration setting. + + Arguments: + key: The name of the configuration setting to extract information for. + default: An optional default value to override the setting's default display value. + """ + global CONFIG_SETTINGS + setting = CONFIG_SETTINGS[key] + + observe_setting(key, 'config') + + cfg_key = setting.get('config_key', None) + cfg_key = f'`{cfg_key}`' if cfg_key else '-' + + default = default or setting.get('default_value', None) + + if default is None: + default = '*Not Specified*' + + return f'| {key} | {cfg_key} | {default} |' + @env.macro def tags_and_filters(): """Return a list of all tags and filters.""" diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index a79df4ce30..ca0bb711ff 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -96,6 +96,8 @@ nav: - Physical Units: concepts/units.md - Companies: concepts/company.md - Custom States: concepts/custom_states.md + - Data Export: concepts/data_export.md + - Data Import: concepts/data_import.md - Pricing: concepts/pricing.md - Project Codes: concepts/project_codes.md - Attachments: concepts/attachments.md @@ -145,11 +147,13 @@ nav: - Stock Expiry: stock/expiry.md - Stock Ownership: stock/owner.md - Test Results: stock/test.md + - Transfer Orders: stock/transfer_order.md - Manufacturing: - Manufacturing: manufacturing/index.md - Bill of Materials: manufacturing/bom.md - Build Orders: manufacturing/build.md - Build Outputs: manufacturing/output.md + - Required Quantity: manufacturing/required.md - Allocating Stock: manufacturing/allocate.md - External Manufacturing: manufacturing/external.md - Example Build Order: manufacturing/example.md @@ -184,8 +188,6 @@ nav: - Multi Factor Authentication: settings/MFA.md - Email Settings: settings/email.md - Experimental Features: settings/experimental.md - - Export Data: settings/export.md - - Import Data: settings/import.md - Operations: - Background Tasks: settings/tasks.md - Error Logs: settings/logs.md @@ -263,6 +265,7 @@ nav: - Stock: app/stock.md - Purchase Orders: app/po.md - Sales Orders: app/so.md + - Build Orders: app/build.md - Settings: app/settings.md - Privacy: app/privacy.md - Translation: app/translation.md diff --git a/docs/requirements.in b/docs/requirements.in index 708b250cba..7e88513072 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -6,5 +6,5 @@ mkdocs-redirects mkdocs-simple-hooks>=0.1,<1.0 mkdocs-include-markdown-plugin neoteroi-mkdocs -mkdocstrings[python]>=0.25.0,<=1.0.3 +mkdocstrings[python]<=1.0.4,>=1.0.4 mkdocs-mermaid2-plugin diff --git a/docs/requirements.txt b/docs/requirements.txt index 78b69bb50d..4248102d6e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,14 +11,14 @@ babel==2.18.0 \ # -c src/backend/requirements.txt # mkdocs-git-revision-date-localized-plugin # mkdocs-material -backrefs==6.1 \ - --hash=sha256:13eafbc9ccd5222e9c1f0bec563e6d2a6d21514962f11e7fc79872fd56cbc853 \ - --hash=sha256:2a2ccb96302337ce61ee4717ceacfbf26ba4efb1d55af86564b8bbaeda39cac1 \ - --hash=sha256:3bba1749aafe1db9b915f00e0dd166cba613b6f788ffd63060ac3485dc9be231 \ - --hash=sha256:4c9d3dc1e2e558965202c012304f33d4e0e477e1c103663fd2c3cc9bb18b0d05 \ - --hash=sha256:a9e99b8a4867852cad177a6430e31b0f6e495d65f8c6c134b68c14c3c95bf4b0 \ - --hash=sha256:c64698c8d2269343d88947c0735cb4b78745bd3ba590e10313fbf3f78c34da5a \ - --hash=sha256:e82bba3875ee4430f4de4b6db19429a27275d95a5f3773c57e9e18abc23fd2b7 +backrefs==6.2 \ + --hash=sha256:08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be \ + --hash=sha256:0fdc7b012420b6b144410342caeb8adc54c6866cf12064abc9bb211302e496f8 \ + --hash=sha256:12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b \ + --hash=sha256:664e33cd88c6840b7625b826ecf2555f32d491800900f5a541f772c485f7cda7 \ + --hash=sha256:c3f4b9cb2af8cda0d87ab4f57800b57b95428488477be164dd2b47be54db0c90 \ + --hash=sha256:e5f805ae09819caa1aa0623b4a83790e7028604aa2b8c73ba602c4454e665de7 \ + --hash=sha256:f44ff4d48808b243b6c0cdc6231e22195c32f77046018141556c66f8bab72a49 # via mkdocs-material beautifulsoup4==4.14.3 \ --hash=sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb \ @@ -28,143 +28,158 @@ bracex==2.6 \ --hash=sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952 \ --hash=sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7 # via wcmatch -certifi==2026.1.4 \ - --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ - --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # -c src/backend/requirements.txt # httpcore # httpx # requests -charset-normalizer==3.4.4 \ - --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ - --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ - --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ - --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ - --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ - --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ - --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ - --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ - --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ - --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ - --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ - --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ - --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ - --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ - --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ - --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ - --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ - --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ - --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ - --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ - --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ - --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ - --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ - --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ - --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ - --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ - --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ - --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ - --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ - --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ - --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ - --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ - --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ - --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ - --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ - --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ - --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ - --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ - --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ - --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ - --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ - --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ - --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ - --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ - --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ - --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ - --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ - --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ - --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ - --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ - --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ - --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ - --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ - --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ - --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ - --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ - --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ - --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ - --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ - --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ - --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ - --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ - --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ - --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ - --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ - --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ - --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ - --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ - --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ - --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ - --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ - --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ - --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ - --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ - --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ - --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ - --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ - --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ - --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ - --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ - --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ - --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ - --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ - --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ - --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ - --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ - --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ - --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ - --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ - --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ - --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ - --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ - --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ - --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ - --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ - --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ - --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ - --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ - --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ - --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ - --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ - --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ - --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ - --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ - --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ - --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ - --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ - --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ - --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ - --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ - --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ - --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ - --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 +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 # via # -c src/backend/requirements.txt # requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # mkdocs # neoteroi-mkdocs + # properdocs colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 - # via - # griffe - # mkdocs-material + # via mkdocs-material editorconfig==0.17.1 \ --hash=sha256:1eda9c2c0db8c16dbd50111b710572a5e6de934e39772de1959d41f64fc17c82 \ --hash=sha256:23c08b00e8e08cc3adcddb825251c497478df1dada6aefeb01e626ad37303745 @@ -173,25 +188,26 @@ essentials==1.1.9 \ --hash=sha256:71ef161e0e27ef77cd6f5fc05e0b8688a575fcab870c01c95940f832e321dfbb \ --hash=sha256:7fbea3a518cbeafe5374fb7e2ea2c15a109e8a7fd1eaab62ae87cbd1b3b1e8d0 # via essentials-openapi -essentials-openapi==1.3.0 \ - --hash=sha256:453327a0a847a431133f4472ced7e4a9180bf667437049b57381ddf88079e886 \ - --hash=sha256:9c2a88531e2c70c565d5b526d74043941e46f60c114f7a0e3ae91e9e6bef4dae +essentials-openapi==1.4.0 \ + --hash=sha256:578c81501ccf6d18c0839d60636214fbd051f0ef37f1d207d4e3c92de2aac008 \ + --hash=sha256:86d879c32734248ad52482a90ee89a32883bce348b4edd323c01556b505b45b9 # via neoteroi-mkdocs ghp-import==2.1.0 \ --hash=sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 \ --hash=sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343 - # via mkdocs + # via + # mkdocs + # properdocs gitdb==4.0.12 \ --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 +gitpython==3.1.50 \ + --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \ + --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 # via mkdocs-git-revision-date-localized-plugin -griffe==1.15.0 \ - --hash=sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3 \ - --hash=sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea +griffelib==2.0.0 \ + --hash=sha256:01284878c966508b6d6f1dbff9b6fa607bc062d8261c5c7253cb285b06422a7f # via mkdocstrings-python h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -211,9 +227,9 @@ httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad # via neoteroi-mkdocs -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.15 \ + --hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \ + --hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc # via # -c src/backend/requirements.txt # anyio @@ -229,6 +245,7 @@ jinja2==3.1.6 \ # mkdocs-material # mkdocstrings # neoteroi-mkdocs + # properdocs jsbeautifier==1.15.4 \ --hash=sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592 \ --hash=sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528 @@ -242,6 +259,7 @@ markdown==3.10.2 \ # mkdocs-autorefs # mkdocs-material # mkdocstrings + # properdocs # pymdown-extensions markdown-it-py==4.0.0 \ --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ @@ -344,6 +362,7 @@ markupsafe==3.0.3 \ # mkdocs # mkdocs-autorefs # mkdocstrings + # properdocs mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba @@ -369,31 +388,31 @@ mkdocs==1.6.1 \ # mkdocs-simple-hooks # mkdocstrings # neoteroi-mkdocs -mkdocs-autorefs==1.4.3 \ - --hash=sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9 \ - --hash=sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75 +mkdocs-autorefs==1.4.4 \ + --hash=sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089 \ + --hash=sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197 # via # mkdocstrings # mkdocstrings-python -mkdocs-get-deps==0.2.0 \ - --hash=sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c \ - --hash=sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134 +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 # via -r docs/requirements.in -mkdocs-include-markdown-plugin==7.2.1 \ - --hash=sha256:30da634c568ea5d5f9e5881d51f80ac30d8c5f891cec160344ad7a0fdaea6286 \ - --hash=sha256:5d94db87b06cd303619dbaebba5f7f43a3ded7fd7709451d26f08c176376ffec +mkdocs-include-markdown-plugin==7.2.2 \ + --hash=sha256:f052ccb741eccf498116b826c1d78a2d761c56747372594709441cee0963fbc9 \ + --hash=sha256:f2ec4487cf32d3e33ca528f9366f20fb9280ded9c8d1630eb2bbda244962dcd1 # 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.1 \ - --hash=sha256:3f6100937d7d731f87f1e3e3b021c97f7239666b9ba1151ab476cabb96c60d5c \ - --hash=sha256:89601b8f2c3e6c6ee0a918cc3566cb201d40bf37c3cd3c2067e26fadb8cce2b8 +mkdocs-material==9.7.6 \ + --hash=sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69 \ + --hash=sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba # via -r docs/requirements.in mkdocs-material-extensions==1.3.1 \ --hash=sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443 \ @@ -403,60 +422,67 @@ mkdocs-mermaid2-plugin==1.2.3 \ --hash=sha256:33f60c582be623ed53829a96e19284fc7f1b74a1dbae78d4d2e47fe00c3e190d \ --hash=sha256:fb6f901d53e5191e93db78f93f219cad926ccc4d51e176271ca5161b6cc5368c # via -r docs/requirements.in -mkdocs-redirects==1.2.2 \ - --hash=sha256:3094981b42ffab29313c2c1b8ac3969861109f58b2dd58c45fc81cd44bfa0095 \ - --hash=sha256:7dbfa5647b79a3589da4401403d69494bd1f4ad03b9c15136720367e1f340ed5 +mkdocs-redirects==1.2.3 \ + --hash=sha256:5e980330999299729a2d6a125347d1af78023d68a23681a4de3053ce7dfe2e51 \ + --hash=sha256:ec7312fff462d03ec16395d0c001006a418f8d0c21cdf2b47ff11cf839dc3ce0 # via -r docs/requirements.in mkdocs-simple-hooks==0.1.5 \ --hash=sha256:dddbdf151a18723c9302a133e5cf79538be8eb9d274e8e07d2ac3ac34890837c \ --hash=sha256:efeabdbb98b0850a909adee285f3404535117159d5cb3a34f541d6eaa644d50a # via -r docs/requirements.in -mkdocstrings[python]==1.0.3 \ - --hash=sha256:0d66d18430c2201dc7fe85134277382baaa15e6b30979f3f3bdbabd6dbdb6046 \ - --hash=sha256:ab670f55040722b49bb45865b2e93b824450fb4aef638b00d7acb493a9020434 +mkdocstrings[python]==1.0.4 \ + --hash=sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172 \ + --hash=sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b # via # -r docs/requirements.in # mkdocstrings-python -mkdocstrings-python==2.0.1 \ - --hash=sha256:66ecff45c5f8b71bf174e11d49afc845c2dfc7fc0ab17a86b6b337e0f24d8d90 \ - --hash=sha256:843a562221e6a471fefdd4b45cc6c22d2607ccbad632879234fa9692e9cf7732 +mkdocstrings-python==2.0.3 \ + --hash=sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 \ + --hash=sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8 # via mkdocstrings neoteroi-mkdocs==1.2.0 \ --hash=sha256:58e25cb1b9db093ffa8d12bdb33264bf567cac30fb964b56e0a493efa749ad6e \ --hash=sha256:91b6aa95a4e46c9bb93e00e021d2044cb0c7d80c0b4600434ff8f440d613a0a8 # via -r docs/requirements.in -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # -c src/backend/requirements.txt # mkdocs # mkdocs-macros-plugin + # properdocs paginate==0.5.7 \ --hash=sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945 \ --hash=sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 # via mkdocs-material -pathspec==1.0.1 \ - --hash=sha256:8870061f22c58e6d83463cfce9a7dd6eca0512c772c1001fb09ac64091816721 \ - --hash=sha256:e2769b508d0dd47b09af6ee2c75b2744a2cb1f474ae4b1494fd6a1b7a841613c +pathspec==1.0.4 \ + --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ + --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 # via # mkdocs # mkdocs-macros-plugin -platformdirs==4.9.2 \ - --hash=sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd \ - --hash=sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291 + # properdocs +platformdirs==4.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via # -c src/backend/requirements.txt # mkdocs-get-deps -pygments==2.19.2 \ - --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ - --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b + # properdocs +properdocs==1.6.7 \ + --hash=sha256:6fa0cfa2e01bf338f684892c8a506cf70ea88ae7f3479c933b6fa20168101cbd \ + --hash=sha256:adc7b16e562890af0e098a7e5b02e3a81c20894a87d6a28d345c9300de73c26e + # via mkdocs-redirects +pygments==2.20.0 \ + --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ + --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # via # mkdocs-material # rich -pymdown-extensions==10.20 \ - --hash=sha256:5c73566ab0cf38c6ba084cb7c5ea64a119ae0500cce754ccb682761dfea13a52 \ - --hash=sha256:ea9e62add865da80a271d00bfa1c0fa085b20d133fb3fc97afdc88e682f60b2f +pymdown-extensions==10.21.3 \ + --hash=sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354 \ + --hash=sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6 # via # mkdocs-material # mkdocs-mermaid2-plugin @@ -548,27 +574,30 @@ pyyaml==6.0.3 \ # mkdocs # mkdocs-get-deps # mkdocs-macros-plugin + # properdocs # pymdown-extensions # pyyaml-env-tag pyyaml-env-tag==1.1 \ --hash=sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 \ --hash=sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff - # via mkdocs -requests==2.32.5 \ - --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ - --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf + # via + # mkdocs + # properdocs +requests==2.33.1 \ + --hash=sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517 \ + --hash=sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # via # -c src/backend/requirements.txt # mkdocs-macros-plugin # mkdocs-material # mkdocs-mermaid2-plugin -rich==14.3.2 \ - --hash=sha256:08e67c3e90884651da3239ea668222d19bea7b589149d8014a21c633420dbb69 \ - --hash=sha256:e712f11c1a562a11843306f5ed999475f09ac31ffb64281f73ab29ffdda8b3b8 +rich==15.0.0 \ + --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ + --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via neoteroi-mkdocs -setuptools==82.0.0 \ - --hash=sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb \ - --hash=sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0 +setuptools==82.0.1 \ + --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ + --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via # -c src/backend/requirements.txt # mkdocs-mermaid2-plugin @@ -579,13 +608,13 @@ six==1.17.0 \ # -c src/backend/requirements.txt # jsbeautifier # python-dateutil -smmap==5.0.2 \ - --hash=sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5 \ - --hash=sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e +smmap==5.0.3 \ + --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ + --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f # via gitdb -soupsieve==2.8.1 \ - --hash=sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350 \ - --hash=sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434 +soupsieve==2.8.3 \ + --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ + --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 # via beautifulsoup4 super-collections==0.6.2 \ --hash=sha256:0c8d8abacd9fad2c7c1c715f036c29f5db213f8cac65f24d45ecba12b4da187a \ @@ -602,9 +631,9 @@ typing-extensions==4.15.0 \ # -c src/backend/requirements.txt # anyio # beautifulsoup4 -urllib3==2.6.3 \ - --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ - --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +urllib3==2.7.0 \ + --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ + --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # via # -c src/backend/requirements.txt # requests @@ -639,7 +668,9 @@ watchdog==6.0.0 \ --hash=sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8 \ --hash=sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c \ --hash=sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2 - # via mkdocs + # via + # mkdocs + # properdocs wcmatch==10.1 \ --hash=sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a \ --hash=sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af diff --git a/pyproject.toml b/pyproject.toml index b8fe778766..169e5a1f89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,16 +108,19 @@ root = ["src/backend/InvenTree"] unresolved-reference="ignore" # 21 # see https://github.com/astral-sh/ty/issues/220 unresolved-attribute="ignore" # 505 # 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-argument-type="ignore" # 49 -possibly-unbound-attribute="ignore" # 25 # https://github.com/astral-sh/ty/issues/164 -unknown-argument="ignore" # 3 # need to wait for betterdjango field stubs -invalid-assignment="ignore" # 17 # need to wait for betterdjango field stubs no-matching-overload="ignore" # 3 # need to wait for betterdjango field stubs +possibly-unbound-attribute="ignore" # 21 [tool.coverage.run] source = ["src/backend/InvenTree", "InvenTree"] dynamic_context = "test_function" +omit = ["*/test_migrations.py"] [tool.coverage.html] show_contexts = true @@ -139,3 +142,4 @@ django_find_project = false pythonpath = ["src/backend/InvenTree"] DJANGO_SETTINGS_MODULE = "InvenTree.settings" python_files = ["test*.py",] +timeout = "120" diff --git a/src/backend/InvenTree/.gitignore b/src/backend/InvenTree/.gitignore index ec668443c9..a91adca39b 100644 --- a/src/backend/InvenTree/.gitignore +++ b/src/backend/InvenTree/.gitignore @@ -1,5 +1,6 @@ # Files generated during unit testing _testfolder/ +_tests_report*.txt # Playwright files for CI InvenTree/static/img/playwright*.png diff --git a/src/backend/InvenTree/InvenTree/api.py b/src/backend/InvenTree/InvenTree/api.py index 79173c6ab4..87edf69474 100644 --- a/src/backend/InvenTree/InvenTree/api.py +++ b/src/backend/InvenTree/InvenTree/api.py @@ -15,7 +15,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 +from rest_framework import serializers, viewsets from rest_framework.generics import GenericAPIView from rest_framework.request import clone_request from rest_framework.response import Response @@ -297,7 +297,7 @@ class InfoView(APIView): 'instance': InvenTree.version.inventreeInstanceName(), 'apiVersion': InvenTree.version.inventreeApiVersion(), 'worker_running': is_worker_running(), - 'worker_count': settings.BACKGROUND_WORKER_COUNT, + 'worker_count': settings.Q_CLUSTER['workers'], 'worker_pending_tasks': self.worker_pending_tasks(), 'plugins_enabled': settings.PLUGINS_ENABLED, 'plugins_install_disabled': settings.PLUGINS_INSTALL_DISABLED, @@ -423,23 +423,19 @@ class BulkOperationMixin: def get_bulk_queryset(self, request): """Return a queryset based on the selection made in the request. - Selection can be made by providing either: - - - items: A list of primary key values - - filters: A dictionary of filter values + Selection can be made by providing a list of primary key values, + which will be used to filter the queryset. """ - model = self.serializer_class.Meta.model - items = request.data.pop('items', None) - filters = request.data.pop('filters', None) all_filter = request.GET.get('all', None) - queryset = model.objects.all() + # Return the base queryset for this model + queryset = self.get_queryset() - if not items and not filters and all_filter is None: + if not items and all_filter is None: raise ValidationError({ 'non_field_errors': _( - 'List of items or filters must be provided for bulk operation' + 'List of items must be provided for bulk operation' ) }) @@ -457,19 +453,6 @@ class BulkOperationMixin: 'non_field_errors': _('Invalid items list provided') }) - if filters: - if type(filters) is not dict: - raise ValidationError({ - 'non_field_errors': _('Filters must be provided as a dict') - }) - - try: - queryset = queryset.filter(**filters) - except Exception: - raise ValidationError({ - 'non_field_errors': _('Invalid filters provided') - }) - if all_filter and not helpers.str2bool(all_filter): raise ValidationError({ 'non_field_errors': _('All filter must only be used with true') @@ -507,7 +490,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 unique_create_fields) + key = tuple(item[v] for v in list(unique_create_fields)) # type: ignore[not-subscriptable] existing[key].append(idx) unique_errors = [[] for _ in range(len(data))] @@ -594,17 +577,24 @@ class BulkUpdateMixin(BulkOperationMixin): n = queryset.count() + instance_data = [] + with transaction.atomic(): # 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: serializer = self.get_serializer(instance, data=data, partial=True) - serializer.is_valid(raise_exception=True) serializer.save() - return Response({'success': f'Updated {n} items'}, status=200) + instance_data.append(serializer.data) + + return Response( + {'success': f'Updated {n} items', 'items': instance_data}, status=200 + ) class ParameterListMixin: @@ -635,12 +625,8 @@ class ParameterListMixin: return queryset -class BulkDeleteMixin(BulkOperationMixin): - """Mixin class for enabling 'bulk delete' operations for various models. - - Bulk delete allows for multiple items to be deleted in a single API query, - rather than using multiple API calls to the various detail endpoints. - """ +class CommonBulkDeleteMixin(BulkOperationMixin): + """Helper for creating bulk delete operation on classic cbv and viewsets.""" def validate_delete(self, queryset, request) -> None: """Perform validation right before deletion. @@ -665,7 +651,7 @@ class BulkDeleteMixin(BulkOperationMixin): return queryset @extend_schema(request=BulkRequestSerializer) - def delete(self, request, *args, **kwargs): + def _delete(self, request, *args, **kwargs): """Perform a DELETE operation against this list endpoint. Note that the typical DRF list endpoint does not support DELETE, @@ -689,6 +675,37 @@ class BulkDeleteMixin(BulkOperationMixin): return Response({'success': f'Deleted {n_deleted} items'}, status=200) +class BulkDeleteMixin(CommonBulkDeleteMixin): + """Mixin class for enabling 'bulk delete' operations for various models. + + Bulk delete allows for multiple items to be deleted in a single API query, + rather than using multiple API calls to the various detail endpoints. + """ + + @extend_schema(request=BulkRequestSerializer) + def delete(self, request, *args, **kwargs): + """Perform a DELETE operation against this list endpoint. + + Note that the typical DRF list endpoint does not support DELETE, + so this method is provided as a custom implementation. + """ + return self._delete(request, *args, **kwargs) + + +class BulkDeleteViewsetMixin(CommonBulkDeleteMixin, viewsets.GenericViewSet): + """Mixin class for enabling 'bulk delete' operations for viewsets.""" + + @extend_schema(request=BulkRequestSerializer) + def bulk_delete(self, request, *args, **kwargs): + """Perform a bulk delete operation. + + Provide either a list of ids (via `items`) or a filter (via `filters`) to select the items to be deleted. + + This action is performed attomically, so either all items will be deleted, or none will be deleted. + """ + return self._delete(request, *args, **kwargs) + + class ListCreateDestroyAPIView(BulkDeleteMixin, ListCreateAPI): """Custom API endpoint which provides BulkDelete functionality in addition to List and Create.""" diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 4d4b72abd2..a8192a2431 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,11 +1,127 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 459 +INVENTREE_API_VERSION = 494 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +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 + +v493 -> 2026-05-22 : https://github.com/inventree/InvenTree/pull/11961 + - Adds "thumbnail" field to the Attachment API endpoint, which provides a URL to a thumbnail image for image attachments (if available) + +v492 -> 2026-05-22 : https://github.com/inventree/InvenTree/pull/11281 + - Add Transfer Order model and associated API endpoint + +v491 -> 2026-05-21 : https://github.com/inventree/InvenTree/pull/11979 + - Add API serializer for deleting a part category + - Add API serializer for deleting a stock location + +v490 -> 2026-05-19 : https://github.com/inventree/InvenTree/pull/11963 + - Moves user-self-filtered endpoints to /user/me/ to make their security boundaries clearer + +v489 -> 2026-05-18 : https://github.com/inventree/InvenTree/pull/11962 + - Removes the "remote_image" field from the Part API endpoint + - Removes the "remote_image" field from the Company API endpoint + +v488 -> 2026-05-17 : https://github.com/inventree/InvenTree/pull/11920 + - Allow renaming of attachments after upload via the API + +v487 -> 2026-05-15 : https://github.com/inventree/InvenTree/pull/11948 + - Make SelectionList default nullable + - Add icon to TreePath schema + +v486 -> 2026-05-10 : https://github.com/inventree/InvenTree/pull/11914 + - Adds "maximum_stock" field to the Part model and associated API endpoints + - Adds "high_stock" filter to the Part API endpoint to filter parts which are above their maximum stock level + +v485 -> 2026-05-10 : https://github.com/inventree/InvenTree/pull/11631 + - Adds "raw_amount" field to the BomItem API endpoint + +v484 -> 2026-05-10 : https://github.com/inventree/InvenTree/pull/11910 + - Adds more docstrings to (scheduled) tasks + +v483 -> 2026-05-04 : https://github.com/inventree/InvenTree/pull/11861 + - Enable bulk-update operations on the BomItem API endpoint, allowing multiple BOM items to be updated in a single API call + +v482 -> 2026-03-15 : https://github.com/inventree/InvenTree/pull/11540 + - Add id to the ordering fields of the Parts model + +v481 -> 2026-04-28 : https://github.com/inventree/InvenTree/pull/11825 + - Adds new "bom" ruleset and associated permissions for BOM management, separate from the "part" ruleset which remains focused on part management + +v480 -> 2026-04-27 : https://github.com/inventree/InvenTree/pull/11816 + - The "issued_by" field on the Build API endpoint is now read-only, and is automatically set to the current user when a build is created + +v479 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11723 + - POST /api/notifications/readall/ now requires a POST action + - POST /api/admin/email/test/ - now returns a 200 on. a successful test + - GET /api/notifications/ - now uses user-centric permissions, not a general read + +v478 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11073 + - Add OptionalField class for cleaner handling of optional fields in serializers + +v477 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11617 + - Non-functional refactor, adaptations of descriptions + +v476 -> 2026-04-09 : https://github.com/inventree/InvenTree/pull/11705 + - Adds sorting / filtering / searching functionality to the SelectionListEntry API endpoint + +v475 -> 2026-04-09 : https://github.com/inventree/InvenTree/pull/11702 + - Adds "updated" and "updated_by" fields to the LabelTemplate and ReportTemplate API endpoints + +v474 -> 2026-04-08 : https://github.com/inventree/InvenTree/pull/11693 + - Adds DataImportMixin to the ManufacturerPartList API endpoint + +v473 -> 2026-04-08 : https://github.com/inventree/InvenTree/pull/11692 + - Adds "line" field to PurchaseOrderLineItem and PurchaseOrderExtraLineItem API endpoints + - Adds "line" field to SalesOrderLineItem and SalesOrderExtraLineItem API endpoints + - Adds "line" field to ReturnOrderLineItem and ReturnOrderExtraLineItem API endpoints + +v472 -> 2026-04-01 : https://github.com/inventree/InvenTree/pull/xxxx + - Fixes writable fields on the user detail endpoint + +v471 -> 2026-04-07 : https://github.com/inventree/InvenTree/pull/11685 + - Adds data importer support for the "SalesOrderShipment" model + +v470 -> 2026-04-01 : https://github.com/inventree/InvenTree/pull/11659 + - Renames "is_staff" field to "is_admin" and updates help texts accordingly to highlight current security boundaries + +v469 -> 2026-03-31 : https://github.com/inventree/InvenTree/pull/11641 + - Adds parameter support to the SalesOrderShipment model and API endpoints + +v468 -> 2026-03-31 : https://github.com/inventree/InvenTree/pull/11649 + - Add ordering to contentype related fields - no functional changes + +v467 -> 2026-03-20 : https://github.com/inventree/InvenTree/pull/11573 + - Fix definition for the "parent" field on the StockItemSerializer + +v466 -> 2026-03-17 : https://github.com/inventree/InvenTree/pull/11525 + - SalesOrderShipmentComplete endpoint now returns a task ID which can be used to track the progress of the shipment completion process + +v465 -> 2026-03-16 : https://github.com/inventree/InvenTree/pull/11529/ + - BuildOrderAutoAllocate endpoint now returns a task ID which can be used to track the progress of the auto-allocation process + - BuildOrderConsume endpoint now returns a task ID which can be used to track the progress of the stock consumption process + +v464 -> 2026-03-15 : https://github.com/inventree/InvenTree/pull/11527 + - Add API endpoint for monitoring the progress of a particular background task + +v463 -> 2026-03-12 : https://github.com/inventree/InvenTree/pull/11499 + - Allow "bulk update" actions against StockItem endpoint + +v462 -> 2026-03-12 : https://github.com/inventree/InvenTree/pull/11497 + - Allow "ScheduledTask" API endpoint to be filtered by "name" field + +v461 -> 2026-03-10 : https://github.com/inventree/InvenTree/pull/11479 + - Adds option to copy parameters when duplicating an order via the API + +v460 -> 2026-02-25 : https://github.com/inventree/InvenTree/pull/11374 + - Adds "updated_at" field to PurchaseOrder, SalesOrder and ReturnOrder API endpoints + - Adds "updated_before" and "updated_after" date filters to all three order list endpoints + - Adds "updated_at" ordering option to all three order list endpoints + v459 -> 2026-02-23 : https://github.com/inventree/InvenTree/pull/11411 - Changed PurchaseOrderLine "auto_pricing" default value from true to false @@ -296,12 +412,6 @@ v381 -> 2025-08-06 : https://github.com/inventree/InvenTree/pull/10132 v380 -> 2025-08-06 : https://github.com/inventree/InvenTree/pull/10135 - Fixes "issued_by" filter for the BuildOrder list API endpoint -v380 -> 2025-08-06 : https://github.com/inventree/InvenTree/pull/10132 - - Refactor the "return stock item" API endpoint to align with other stock adjustment actions - -v380 -> 2025-08-06 : https://github.com/inventree/InvenTree/pull/10135 - - Fixes "issued_by" filter for the BuildOrder list API endpoint - v379 -> 2025-08-04 : https://github.com/inventree/InvenTree/pull/10124 - Removes "PartStocktakeReport" model and associated API endpoints - Remove "last_stocktake" field from the Part model diff --git a/src/backend/InvenTree/InvenTree/apps.py b/src/backend/InvenTree/InvenTree/apps.py index a04148c040..50d5b6ae5d 100644 --- a/src/backend/InvenTree/InvenTree/apps.py +++ b/src/backend/InvenTree/InvenTree/apps.py @@ -65,10 +65,12 @@ class InvenTreeConfig(AppConfig): self.start_background_tasks() if not InvenTree.ready.isInTestMode(): # pragma: no cover - # Update exchange rates - InvenTree.tasks.offload_task(InvenTree.tasks.update_exchange_rates) # Let the background worker check for migrations InvenTree.tasks.offload_task(InvenTree.tasks.check_for_migrations) + # Update exchange rates + InvenTree.tasks.offload_task( + InvenTree.tasks.update_exchange_rates, force_async=True + ) self.update_site_url() self.load_unit_registry() diff --git a/src/backend/InvenTree/InvenTree/cache.py b/src/backend/InvenTree/InvenTree/cache.py index 00214610cc..07547eb667 100644 --- a/src/backend/InvenTree/InvenTree/cache.py +++ b/src/backend/InvenTree/InvenTree/cache.py @@ -50,6 +50,11 @@ def cache_user(): return cache_setting('user', None) +def cache_db(): + """Return the cache database index.""" + return cache_setting('db', 0, typecast=int) + + def is_global_cache_enabled() -> bool: """Check if the global cache is enabled. @@ -89,49 +94,51 @@ def get_cache_config(global_cache: bool) -> dict: Returns: A dictionary containing the cache configuration options. """ - if global_cache: - # Build Redis URL with optional password - password = cache_password() - user = cache_user() or '' + # Build Redis URL with optional password + password = cache_password() + user = cache_user() or '' + host = cache_host() + port = cache_port() + db = cache_db() - if password: - redis_url = f'redis://{user}:{password}@{cache_host()}:{cache_port()}/0' - else: - redis_url = f'redis://{cache_host()}:{cache_port()}/0' + if password: + redis_url = f'redis://{user}:{password}@{host}:{port}/{db}' + else: + redis_url = f'redis://{host}:{port}/{db}' - keepalive_options = { - 'TCP_KEEPCNT': cache_setting('keepalive_count', 5, typecast=int), - 'TCP_KEEPIDLE': cache_setting('keepalive_idle', 1, typecast=int), - 'TCP_KEEPINTVL': cache_setting('keepalive_interval', 1, typecast=int), - 'TCP_USER_TIMEOUT': cache_setting('user_timeout', 1000, typecast=int), - } + keepalive_options = { + 'TCP_KEEPCNT': cache_setting('keepalive_count', 5, typecast=int), + 'TCP_KEEPIDLE': cache_setting('keepalive_idle', 1, typecast=int), + 'TCP_KEEPINTVL': cache_setting('keepalive_interval', 1, typecast=int), + 'TCP_USER_TIMEOUT': cache_setting('user_timeout', 1000, typecast=int), + } - return { - 'BACKEND': 'django_redis.cache.RedisCache', - 'LOCATION': redis_url, - 'OPTIONS': { - 'CLIENT_CLASS': 'django_redis.client.DefaultClient', - 'SOCKET_CONNECT_TIMEOUT': cache_setting( - 'connect_timeout', 5, typecast=int - ), - 'SOCKET_TIMEOUT': cache_setting('timeout', 3, typecast=int), - 'CONNECTION_POOL_KWARGS': { - 'socket_keepalive': cache_setting( - 'tcp_keepalive', True, typecast=bool - ), - 'socket_keepalive_options': { - # Only include options which are available on this platform - # e.g. MacOS does not have TCP_KEEPIDLE and TCP_USER_TIMEOUT - getattr(socket, key): value - for key, value in keepalive_options.items() - if hasattr(socket, key) - }, + global_cache_config = { + 'BACKEND': 'django_redis.cache.RedisCache', + 'LOCATION': redis_url, + 'OPTIONS': { + 'CLIENT_CLASS': 'django_redis.client.DefaultClient', + 'SOCKET_CONNECT_TIMEOUT': cache_setting('connect_timeout', 5, typecast=int), + 'SOCKET_TIMEOUT': cache_setting('timeout', 3, typecast=int), + 'CONNECTION_POOL_KWARGS': { + 'socket_keepalive': cache_setting('tcp_keepalive', True, typecast=bool), + 'socket_keepalive_options': { + # Only include options which are available on this platform + # e.g. MacOS does not have TCP_KEEPIDLE and TCP_USER_TIMEOUT + getattr(socket, key): value + for key, value in keepalive_options.items() + if hasattr(socket, key) }, }, - } + }, + } - # Default: Use django local memory cache - return {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'} + if global_cache: + # Only return the global cache configuration if the global cache is enabled + return global_cache_config + else: + # Default: Use django local memory cache + return {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'} def create_session_cache(request) -> None: diff --git a/src/backend/InvenTree/InvenTree/config.py b/src/backend/InvenTree/InvenTree/config.py index 86ebe87339..c6da6eaf71 100644 --- a/src/backend/InvenTree/InvenTree/config.py +++ b/src/backend/InvenTree/InvenTree/config.py @@ -9,7 +9,7 @@ import shutil import string import sys from pathlib import Path -from typing import Optional +from typing import Any, Optional logger = logging.getLogger('inventree') CONFIG_DATA = None @@ -188,7 +188,7 @@ def load_config_data(set_cache: bool = False) -> map | None: if CONFIG_DATA is not None and not set_cache: return CONFIG_DATA - import yaml + import yaml.parser cfg_file = get_config_file() @@ -251,6 +251,24 @@ def do_typecast(value, type, var_name=None): return value +def get_config_value(config_key: str) -> Optional[Any]: + """Helper function to retrieve a configuration value from the config file.""" + cfg_data = load_config_data() + + result = None + + # Hack to allow 'path traversal' in configuration file + for key in config_key.strip().split('.'): + if type(cfg_data) is not dict or key not in cfg_data: + result = None + break + + result = cfg_data[key] + cfg_data = cfg_data[key] + + return result + + def get_setting(env_var=None, config_key=None, default_value=None, typecast=None): """Helper function for retrieving a configuration setting value. @@ -267,10 +285,13 @@ def get_setting(env_var=None, config_key=None, default_value=None, typecast=None def set_metadata(source: str): """Set lookup metadata for the setting.""" + global CONFIG_LOOKUPS + key = env_var or config_key CONFIG_LOOKUPS[key] = { 'env_var': env_var, 'config_key': config_key, + 'default_value': default_value, 'source': source, 'accessed': datetime.datetime.now(), } @@ -285,18 +306,7 @@ def get_setting(env_var=None, config_key=None, default_value=None, typecast=None # Next, try to load from configuration file if config_key is not None: - cfg_data = load_config_data() - - result = None - - # Hack to allow 'path traversal' in configuration file - for key in config_key.strip().split('.'): - if type(cfg_data) is not dict or key not in cfg_data: - result = None - break - - result = cfg_data[key] - cfg_data = cfg_data[key] + result = get_config_value(config_key) if result is not None: set_metadata('yaml') @@ -533,13 +543,14 @@ def get_frontend_settings(debug=True): 'INVENTREE_FRONTEND_SETTINGS', 'frontend_settings', {}, typecast=dict ) + base_url = get_setting( + 'INVENTREE_FRONTEND_URL_BASE', 'frontend_url_base', 'web', typecast=str + ) + # Set the base URL for the user interface # This is the UI path e.g. '/web/' if 'base_url' not in frontend_settings: - frontend_settings['base_url'] = ( - get_setting('INVENTREE_FRONTEND_URL_BASE', 'frontend_url_base', 'web') - or 'web' - ) + frontend_settings['base_url'] = base_url # If provided, specify the API host api_host = frontend_settings.get('api_host', None) or get_setting( diff --git a/src/backend/InvenTree/InvenTree/conversion.py b/src/backend/InvenTree/InvenTree/conversion.py index aedf416883..8db0eb8330 100644 --- a/src/backend/InvenTree/InvenTree/conversion.py +++ b/src/backend/InvenTree/InvenTree/conversion.py @@ -184,7 +184,7 @@ def from_engineering_notation(value): return value -def convert_value(value, unit): +def convert_value(value, unit=None): """Attempt to convert a value to a specified unit. Arguments: @@ -221,11 +221,11 @@ def convert_physical_value(value: str, unit: Optional[str] = None, strip_units=T unit: Optional unit to convert to, and validate against strip_units: If True, strip units from the returned value, and return only the dimension - Raises: - ValidationError: If the value is invalid or cannot be converted to the specified unit - Returns: The converted quantity, in the specified units + + Raises: + ValidationError: If the value is invalid or cannot be converted to the specified unit """ ureg = get_unit_registry() diff --git a/src/backend/InvenTree/InvenTree/exceptions.py b/src/backend/InvenTree/InvenTree/exceptions.py index dbb623eb5b..161860339d 100644 --- a/src/backend/InvenTree/InvenTree/exceptions.py +++ b/src/backend/InvenTree/InvenTree/exceptions.py @@ -66,7 +66,7 @@ def log_error( data = error_data else: try: - formatted_exception = traceback.format_exception(kind, info, data) # type: ignore[no-matching-overload] + formatted_exception = traceback.format_exception(kind, info, data) data = '\n'.join(formatted_exception) except AttributeError: data = 'No traceback information available' diff --git a/src/backend/InvenTree/InvenTree/filters.py b/src/backend/InvenTree/InvenTree/filters.py index 78c5c5e455..44319b843f 100644 --- a/src/backend/InvenTree/InvenTree/filters.py +++ b/src/backend/InvenTree/InvenTree/filters.py @@ -111,9 +111,11 @@ class InvenTreeOrderingFilter(filters.OrderingFilter): def get_ordering(self, request, queryset, view): """Override ordering for supporting aliases.""" - ordering = super().get_ordering(request, queryset, view) + ordering = list(super().get_ordering(request, queryset, view) or []) aliases = getattr(view, 'ordering_field_aliases', None) + lookup_field = getattr(view, 'lookup_field', 'pk') + lookup_reversed = len(ordering) > 0 and ordering[-1].startswith('-') # Attempt to map ordering fields based on provided aliases if ordering is not None and aliases is not None: @@ -123,9 +125,8 @@ class InvenTreeOrderingFilter(filters.OrderingFilter): ordering = [] for field in ordering_initial: - reverse = field.startswith('-') - - if reverse: + field_reversed = field.startswith('-') + if field_reversed: field = field[1:] # Are aliases defined for this field? @@ -153,11 +154,22 @@ class InvenTreeOrderingFilter(filters.OrderingFilter): continue for a in alias: - if reverse: + if field_reversed: a = '-' + a ordering.append(a) + # Ensure that any API filtering appends the primary-key field + # This is to prevent "ambiguous ordering" errors across pagination boundaries + # Ref: https://github.com/inventree/InvenTree/issues/11442 + if lookup_field and not any( + field in ordering for field in [lookup_field, f'-{lookup_field}'] + ): + if lookup_reversed: + ordering.append(f'-{lookup_field}') + else: + ordering.append(lookup_field) + return ordering @@ -220,18 +232,10 @@ class NumericInFilter(rest_filters.BaseInFilter): return super().filter(qs, numeric_values) -SEARCH_ORDER_FILTER = [ - drf_backend.DjangoFilterBackend, - InvenTreeSearchFilter, - filters.OrderingFilter, -] +ORDER_FILTER = [drf_backend.DjangoFilterBackend, InvenTreeOrderingFilter] -SEARCH_ORDER_FILTER_ALIAS = [ +SEARCH_ORDER_FILTER = [ drf_backend.DjangoFilterBackend, InvenTreeSearchFilter, InvenTreeOrderingFilter, ] - -ORDER_FILTER = [drf_backend.DjangoFilterBackend, filters.OrderingFilter] - -ORDER_FILTER_ALIAS = [drf_backend.DjangoFilterBackend, InvenTreeOrderingFilter] diff --git a/src/backend/InvenTree/InvenTree/helpers.py b/src/backend/InvenTree/InvenTree/helpers.py index efa4d355c6..502ac9c3b0 100644 --- a/src/backend/InvenTree/InvenTree/helpers.py +++ b/src/backend/InvenTree/InvenTree/helpers.py @@ -8,6 +8,7 @@ import json import os.path import re from decimal import Decimal, InvalidOperation +from pathlib import Path from typing import Optional, TypeVar from wsgiref.util import FileWrapper from zoneinfo import ZoneInfo, ZoneInfoNotFoundError @@ -21,19 +22,19 @@ from django.http import StreamingHttpResponse from django.utils import timezone from django.utils.translation import gettext_lazy as _ -import bleach -import bleach.css_sanitizer -import bleach.sanitizer +import nh3 import structlog -from bleach import clean from djmoney.money import Money from PIL import Image from stdimage.models import StdImageField, StdImageFieldFile from common.currency import currency_code_default - -from .setting.storages import StorageBackends -from .settings import MEDIA_URL, STATIC_URL +from InvenTree.sanitizer import ( + DEAFAULT_ATTRS, + DEFAULT_CSS, + DEFAULT_PROTOCOLS, + DEFAULT_TAGS, +) logger = structlog.get_logger('inventree') @@ -186,9 +187,8 @@ def getMediaUrl( ) if name is not None: file = regenerate_imagefile(file, name) - if settings.STORAGE_TARGET == StorageBackends.S3: - return str(file.url) - return os.path.join(MEDIA_URL, str(file.url)) + + return default_storage.url(file.name) def regenerate_imagefile(_file, _name: str): @@ -199,7 +199,7 @@ def regenerate_imagefile(_file, _name: str): _name: Name of the variation (e.g. 'thumbnail', 'preview') """ name = _file.field.attr_class.get_variation_name(_file.name, _name) - return ImageFieldFile(_file.instance, _file, name) # type: ignore + return ImageFieldFile(_file.instance, _file, name) # ty:ignore[too-many-positional-arguments] def image2name(img_obj: StdImageField, do_preview: bool, do_thumbnail: bool): @@ -226,11 +226,18 @@ def image2name(img_obj: StdImageField, do_preview: bool, do_thumbnail: bool): def getStaticUrl(filename): """Return the qualified access path for the given file, under the static media directory.""" - return os.path.join(STATIC_URL, str(filename)) + return StaticFilesStorage().url(filename) -def TestIfImage(img): - """Test if an image file is indeed an image.""" +def TestIfImage(img) -> bool: + """Test if an image file is indeed an image. + + Arguments: + img: A file-like object + + Returns: + True if the file is a valid image, False otherwise + """ try: Image.open(img).verify() return True @@ -248,6 +255,13 @@ def getBlankThumbnail(): return getStaticUrl('img/blank_image.thumbnail.png') +def checkStaticFile(*args) -> bool: + """Check if a file exists in the static storage.""" + static_storage = StaticFilesStorage() + fn = Path(*args) + return static_storage.exists(str(fn)) + + def getLogoImage(as_file=False, custom=True): """Return the InvenTree logo image, or a custom logo if available.""" if custom and settings.CUSTOM_LOGO: @@ -311,7 +325,7 @@ def TestIfImageURL(url): ] -def str2bool(text, test=True): +def str2bool(text, test=True) -> bool: """Test if a string 'looks' like a boolean value. Args: @@ -881,13 +895,13 @@ def clean_decimal(number): def strip_html_tags(value: str, raise_error=True, field_name=None): - """Strip HTML tags from an input string using the bleach library. + """Strip HTML tags from an input string using the nh3 library. If raise_error is True, a ValidationError will be thrown if HTML tags are detected """ value = str(value).strip() - cleaned = clean(value, strip=True, tags=[], attributes=[]) + cleaned = nh3.clean(value, tags=frozenset()) # Add escaped characters back in replacements = {'>': '>', '<': '<', '&': '&'} @@ -947,34 +961,32 @@ def clean_markdown(value: str) -> str: output_format='html', ) - # Bleach settings - whitelist_tags = markdownify_settings.get( - 'WHITELIST_TAGS', bleach.sanitizer.ALLOWED_TAGS - ) - whitelist_attrs = markdownify_settings.get( - 'WHITELIST_ATTRS', bleach.sanitizer.ALLOWED_ATTRIBUTES - ) - whitelist_styles = markdownify_settings.get( - 'WHITELIST_STYLES', bleach.css_sanitizer.ALLOWED_CSS_PROPERTIES - ) + # nh3 sanitizer settings + whitelist_tags = markdownify_settings.get('WHITELIST_TAGS', DEFAULT_TAGS) + whitelist_attrs = markdownify_settings.get('WHITELIST_ATTRS', DEAFAULT_ATTRS) + whitelist_styles = markdownify_settings.get('WHITELIST_STYLES', DEFAULT_CSS) whitelist_protocols = markdownify_settings.get( - 'WHITELIST_PROTOCOLS', bleach.sanitizer.ALLOWED_PROTOCOLS + 'WHITELIST_PROTOCOLS', DEFAULT_PROTOCOLS ) - strip = markdownify_settings.get('STRIP', True) - css_sanitizer = bleach.css_sanitizer.CSSSanitizer( - allowed_css_properties=whitelist_styles - ) - cleaner = bleach.Cleaner( - tags=whitelist_tags, - attributes=whitelist_attrs, - css_sanitizer=css_sanitizer, - protocols=whitelist_protocols, - strip=strip, - ) + # Convert bleach-style attributes (list or dict) to nh3-compatible dict format + if isinstance(whitelist_attrs, (list, tuple, set, frozenset)): + attrs_dict = {'*': set(whitelist_attrs)} + elif isinstance(whitelist_attrs, dict): + attrs_dict = {tag: set(allowed) for tag, allowed in whitelist_attrs.items()} + else: + attrs_dict = None # Clean the HTML content (for comparison). This must be the same as the original content - clean_html = cleaner.clean(html) + clean_html = nh3.clean( + html, + tags=set(whitelist_tags), + attributes=attrs_dict, + url_schemes=set(whitelist_protocols), + filter_style_properties=set(whitelist_styles), + link_rel=None, + strip_comments=True, + ) if html != clean_html: raise ValidationError(_('Data contains prohibited markdown content')) @@ -1169,3 +1181,18 @@ def plugins_info(*args, **kwargs): return [ {'name': plg.name, 'slug': plg.slug, 'version': plg.version} for plg in plugins ] + + +def sanitize_token(token_value: str, front=8, back=12) -> str: + """Sanitize a token by replacing the middle characters with asterisks. + + Args: + token_value: The token string to sanitize + front: Number of characters to show at the start of the token (default = 8) + back: Number of characters to show at the end of the token (default = 12) + + Returns: + The sanitized token string + """ + middle = len(token_value) - (front + back) + return token_value[:front] + '*' * middle + token_value[-back:] diff --git a/src/backend/InvenTree/InvenTree/helpers_api.py b/src/backend/InvenTree/InvenTree/helpers_api.py new file mode 100644 index 0000000000..03c2bf4fda --- /dev/null +++ b/src/backend/InvenTree/InvenTree/helpers_api.py @@ -0,0 +1,49 @@ +"""Helpers for InvenTrees way of using drf viewset.""" + +from rest_framework import mixins, routers, viewsets + +from InvenTree.api import BulkDeleteViewsetMixin + + +class RetrieveUpdateDestroyModelViewSet( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + mixins.ListModelMixin, + viewsets.GenericViewSet, +): + """Viewset which provides 'retrieve', 'update', 'destroy' and 'list' actions.""" + + +class RetrieveDestroyModelViewSet( + mixins.RetrieveModelMixin, + mixins.DestroyModelMixin, + mixins.ListModelMixin, + viewsets.GenericViewSet, +): + """Viewset which provides 'retrieve', 'destroy' and 'list' actions.""" + + +class InvenTreeApiRouter(routers.SimpleRouter): + """Custom router which adds various specific functions. + + Currently adds the following features: + - support for bulk delete operations + """ + + def get_routes(self, viewset): + """Override the default get_routes method to add bulk delete support.""" + routes = super().get_routes(viewset) + + if issubclass(viewset, BulkDeleteViewsetMixin): + list_route = next( + (route for route in routes if route.mapping.get('get') == 'list'), None + ) + list_route.mapping['delete'] = 'bulk_delete' + + return routes + + def get_default_basename(self, viewset): + """Extract the default base name from the viewset.""" + basename = super().get_default_basename(viewset) + return 'api-' + basename diff --git a/src/backend/InvenTree/InvenTree/helpers_email.py b/src/backend/InvenTree/InvenTree/helpers_email.py index de90c0d323..f6dca007f2 100644 --- a/src/backend/InvenTree/InvenTree/helpers_email.py +++ b/src/backend/InvenTree/InvenTree/helpers_email.py @@ -8,6 +8,7 @@ import structlog from allauth.account.models import EmailAddress import InvenTree.ready +import InvenTree.tasks as tasks from common.models import Priority, issue_mail logger = structlog.get_logger('inventree') @@ -98,7 +99,7 @@ def send_email( ) return False, 'INVE-W7: no from_email or DEFAULT_FROM_EMAIL specified' - InvenTree.tasks.offload_task( + tasks.offload_task( issue_mail, subject=subject, body=body, diff --git a/src/backend/InvenTree/InvenTree/helpers_model.py b/src/backend/InvenTree/InvenTree/helpers_model.py index 5fa5ae3cea..ccd1cfd963 100644 --- a/src/backend/InvenTree/InvenTree/helpers_model.py +++ b/src/backend/InvenTree/InvenTree/helpers_model.py @@ -1,9 +1,11 @@ """Provides helper functions used throughout the InvenTree project that access the database.""" import io +import ipaddress +import socket from decimal import Decimal from typing import Optional, cast -from urllib.parse import urljoin +from urllib.parse import urljoin, urlparse from django.conf import settings from django.core.exceptions import ValidationError @@ -88,7 +90,42 @@ def construct_absolute_url(*arg, base_url=None, request=None): return urljoin(base_url, relative_url) -def download_image_from_url(remote_url, timeout=2.5): +def validate_url_no_ssrf(url): + """Validate that a URL does not point to a private/internal network address. + + Resolves the hostname to an IP address and checks it against private, + loopback, link-local, and reserved IP ranges to prevent SSRF attacks. + + Arguments: + url: The URL to validate + + Raises: + ValueError: If the URL resolves to a private or reserved IP address + """ + parsed = urlparse(url) + hostname = parsed.hostname + + if not hostname: + raise ValueError(_('Invalid URL: no hostname')) + + try: + addrinfo = socket.getaddrinfo(hostname, None) + except socket.gaierror: + 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: + raise ValueError(_('URL points to a private or reserved IP address')) + + +def download_image_from_url( + remote_url: str, + timeout: float = 2.5, + user_agent: str = '', + max_size: Optional[int] = None, +): """Download an image file from a remote URL. This is a potentially dangerous operation, so we must perform some checks: @@ -98,8 +135,9 @@ def download_image_from_url(remote_url, timeout=2.5): Arguments: remote_url: The remote URL to retrieve image - max_size: Maximum allowed image size (default = 1MB) timeout: Connection timeout in seconds (default = 5) + user_agent: User-Agent string to use for the request (optional) + max_size: Maximum allowed image size (in bytes) (default = 1MB) Returns: An in-memory PIL image file, if the download was successful @@ -115,24 +153,49 @@ def download_image_from_url(remote_url, timeout=2.5): validator = URLValidator() validator(remote_url) + # SSRF protection: validate the resolved IP is not private/internal + validate_url_no_ssrf(remote_url) + # Calculate maximum allowable image size (in bytes) - max_size = ( - int(get_global_setting('INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE')) * 1024 * 1024 - ) + max_size = max_size or 1 * 1024 * 1024 # Default to 1MB if not provided # Add user specified user-agent to request (if specified) - user_agent = get_global_setting('INVENTREE_DOWNLOAD_FROM_URL_USER_AGENT') - headers = {'User-Agent': user_agent} if user_agent else None try: response = requests.get( remote_url, timeout=timeout, - allow_redirects=True, + 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')) + # Throw an error if anything goes wrong response.raise_for_status() except requests.exceptions.ConnectionError as exc: @@ -143,6 +206,8 @@ def download_image_from_url(remote_url, timeout=2.5): raise requests.exceptions.HTTPError( _('Server responded with invalid status code') + f': {response.status_code}' ) + except ValueError: + raise except Exception as exc: raise Exception(_('Exception occurred') + f': {exc!s}') @@ -288,6 +353,8 @@ def getModelsWithMixin(mixin_class) -> list: models_with_mixin = [ x for x in db_models if x is not None and issubclass(x, mixin_class) ] + # sort to make resulting list deterministic (and easier to test) + models_with_mixin.sort(key=lambda x: x._meta.label_lower) # Store the result in the session cache set_session_cache(cache_key, models_with_mixin) diff --git a/src/backend/InvenTree/InvenTree/logging.py b/src/backend/InvenTree/InvenTree/logging.py new file mode 100644 index 0000000000..e6d7b59226 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/logging.py @@ -0,0 +1,17 @@ +"""Helpers for logging integrations.""" + +from django.dispatch import receiver + +import structlog +from django_structlog import signals + + +@receiver(signals.update_failure_response) +@receiver(signals.bind_extra_request_finished_metadata) +def add_request_id_to_response(response, logger, **kwargs): + """Add the request ID to the response header, so that it can be traced through logs. + + source: https://django-structlog.readthedocs.io/en/latest/how_tos.html#bind-request-id-to-response-s-header + """ + context = structlog.contextvars.get_merged_contextvars(logger) + response['X-InvenTree-ReqId'] = context['request_id'] diff --git a/src/backend/InvenTree/InvenTree/management/commands/export_settings_definitions.py b/src/backend/InvenTree/InvenTree/management/commands/export_settings_definitions.py index fef25f676a..09199f06db 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/export_settings_definitions.py +++ b/src/backend/InvenTree/InvenTree/management/commands/export_settings_definitions.py @@ -24,8 +24,9 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): """Export settings information to a JSON file.""" from common.models import InvenTreeSetting, InvenTreeUserSetting + from InvenTree.config import CONFIG_LOOKUPS - settings = {'global': {}, 'user': {}} + settings = {'global': {}, 'user': {}, 'config': {}} # Global settings for key, setting in InvenTreeSetting.SETTINGS.items(): @@ -45,6 +46,18 @@ class Command(BaseCommand): 'units': str(setting.get('units', '')), } + # Configuration settings + for key, config in CONFIG_LOOKUPS.items(): + default_value = config.get('default_value', None) + if default_value is not None: + default_value = str(default_value) + + settings['config'][key] = { + 'env_var': str(config.get('env_var', '')), + 'config_key': str(config.get('config_key', '')), + 'default_value': default_value, + } + filename = kwargs.get('filename', 'inventree_settings.json') with open(filename, 'w', encoding='utf-8') as f: diff --git a/src/backend/InvenTree/InvenTree/management/commands/list_apps.py b/src/backend/InvenTree/InvenTree/management/commands/list_apps.py new file mode 100644 index 0000000000..56db10e350 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/management/commands/list_apps.py @@ -0,0 +1,29 @@ +"""Custom management command to list all installed apps. + +This is used to determine which apps are installed, +including any apps which are defined for plugins. +""" + +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + """List all installed apps.""" + + def handle(self, *args, **kwargs): + """List all installed apps. + + Note that this function outputs in a particular format, + which is expected by the calling code in tasks.py + """ + from django.apps import apps + + app_list = [] + + for app in apps.get_app_configs(): + app_list.append(app.name) + + app_list.sort() + + self.stdout.write(f'Installed Apps: {len(app_list)}') + self.stdout.write('>>> ' + ','.join(app_list) + ' <<<') diff --git a/src/backend/InvenTree/InvenTree/management/commands/migrate_icons.py b/src/backend/InvenTree/InvenTree/management/commands/migrate_icons.py index 1ff5e6fd62..ee8456fe4f 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/migrate_icons.py +++ b/src/backend/InvenTree/InvenTree/management/commands/migrate_icons.py @@ -99,7 +99,7 @@ class Command(BaseCommand): if kwargs['include_items']: icons[icon]['items'].append({ 'model': model.__name__.lower(), - 'id': item.id, # type: ignore + 'id': item.id, }) self.stdout.write(f'Writing icon map for {len(icons.keys())} icons') diff --git a/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py b/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py index d4b133d5ab..3025f37eb6 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py +++ b/src/backend/InvenTree/InvenTree/management/commands/rebuild_thumbnails.py @@ -3,8 +3,7 @@ - May be required after importing a new dataset, for example """ -import os - +from django.core.files.storage import default_storage from django.core.management.base import BaseCommand from django.db.utils import OperationalError, ProgrammingError @@ -35,7 +34,7 @@ class Command(BaseCommand): img_paths.append(x.path) if len(img_paths) > 0: - if all(os.path.exists(path) for path in img_paths): + if all(default_storage.exists(p) for p in img_paths): # All images exist - skip further work return diff --git a/src/backend/InvenTree/InvenTree/management/commands/wait_for_db.py b/src/backend/InvenTree/InvenTree/management/commands/wait_for_db.py index 68b33adfff..84fcb2ebff 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/wait_for_db.py +++ b/src/backend/InvenTree/InvenTree/management/commands/wait_for_db.py @@ -13,25 +13,39 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): """Wait till the database is ready.""" - self.stdout.write('Waiting for database...') - connected = False + verbose = int(kwargs.get('verbosity', 0)) > 0 + attempts = kwargs.get('attempts', 10) - while not connected: - time.sleep(2) + if verbose: + self.stdout.write('Waiting for database connection...') + self.stdout.flush() + + while not connected and attempts > 0: + attempts -= 1 try: connection.ensure_connection() connected = True - except OperationalError as e: - self.stdout.write(f'Could not connect to database: {e}') - except ImproperlyConfigured as e: - self.stdout.write(f'Improperly configured: {e}') + except (OperationalError, ImproperlyConfigured): + if verbose: + self.stdout.write('Database connection failed, retrying ...') + self.stdout.flush() else: if not connection.is_usable(): - self.stdout.write('Database configuration is not usable') + if verbose: + self.stdout.write('Database configuration is not usable') + self.stdout.flush() if connected: - self.stdout.write('Database connection successful!') + if verbose: + self.stdout.write('Database connection successful!') + self.stdout.flush() + else: + time.sleep(1) + + if not connected: + self.stderr.write('Failed to connect to database after multiple attempts') + self.stderr.flush() diff --git a/src/backend/InvenTree/InvenTree/metadata.py b/src/backend/InvenTree/InvenTree/metadata.py index c45c20e832..4d8451e2db 100644 --- a/src/backend/InvenTree/InvenTree/metadata.py +++ b/src/backend/InvenTree/InvenTree/metadata.py @@ -5,7 +5,7 @@ from django.http import Http404 from django.urls import reverse import structlog -from rest_framework import exceptions, serializers +from rest_framework import exceptions, permissions, serializers from rest_framework.fields import empty from rest_framework.metadata import SimpleMetadata from rest_framework.request import clone_request @@ -131,10 +131,26 @@ class InvenTreeMetadata(SimpleMetadata): # Remove any HTTP methods that the user does not have permission for for method, permission in rolemap.items(): + # general model / role permission result = check_user_permission(user, self.model, permission) or ( role_required and check_user_role(user, role_required, permission) ) + # check if simple IsAuthenticated permission class is used + if not result: + result = ( + view.permission_classes + and len(view.permission_classes) == 1 + and any( + perm + in [ + permissions.IsAuthenticated, + InvenTree.permissions.IsAuthenticatedOrReadScope, + ] + for perm in view.permission_classes + ) + ) + if method in actions and not result: del actions[method] @@ -364,6 +380,15 @@ class InvenTreeMetadata(SimpleMetadata): We take the regular DRF metadata and add our own unique flavor """ + from InvenTree.serializers import OptionalField + + if isinstance(field, OptionalField) or issubclass( + field.__class__, OptionalField + ): + # Rehydrate the OptionalField for proper introspection + rehydrated_field = field.serializer_class(**(field.serializer_kwargs or {})) + return self.get_field_info(rehydrated_field) + # Try to add the child property to the dependent field to be used by the super call if self.label_lookup[field] == 'dependent field': field.get_child(raise_exception=True) diff --git a/src/backend/InvenTree/InvenTree/middleware.py b/src/backend/InvenTree/InvenTree/middleware.py index efed42d59c..98ffc08c22 100644 --- a/src/backend/InvenTree/InvenTree/middleware.py +++ b/src/backend/InvenTree/InvenTree/middleware.py @@ -10,15 +10,21 @@ from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import redirect, render from django.urls import resolve, reverse, reverse_lazy from django.utils.deprecation import MiddlewareMixin -from django.utils.http import is_same_domain +from django.utils.http import is_same_domain, url_has_allowed_host_and_scheme from django.utils.translation import gettext_lazy as _ import structlog from error_report.middleware import ExceptionProcessor +import InvenTree.helpers from common.settings import get_global_setting from InvenTree.cache import create_session_cache, delete_session_cache from InvenTree.config import CONFIG_LOOKUPS, inventreeInstaller +from InvenTree.version import ( + inventreeApiVersion, + inventreePythonVersion, + inventreeVersion, +) from users.models import ApiToken logger = structlog.get_logger('inventree') @@ -121,7 +127,8 @@ class AuthRequiredMiddleware: return True except ApiToken.DoesNotExist: # pragma: no cover logger.warning( - 'Access denied for unknown token %s', token + 'Access denied for unknown token %s', + InvenTree.helpers.sanitize_token(str(token)), ) # pragma: no cover return False @@ -158,9 +165,16 @@ class AuthRequiredMiddleware: if path not in urls and not any( path.startswith(p) for p in paths_ignore_handling ): + # Validate next url is safe to redirect to + next_url = request.path + if not url_has_allowed_host_and_scheme( + url=next_url, + allowed_hosts=settings.ALLOWED_HOSTS, + require_https=request.is_secure(), + ): + return redirect(str(reverse_lazy('account_login'))) # Save the 'next' parameter to pass through to the login view - - return redirect(f'{reverse_lazy("account_login")}?next={request.path}') + return redirect(f'{reverse_lazy("account_login")}?next={next_url}') # Return a 401 (Unauthorized) response code for this request return HttpResponse('Unauthorized', status=401) @@ -393,3 +407,15 @@ class InvenTreeHostSettingsMiddleware(MiddlewareMixin): # All checks passed return None + + +class InvenTreeVersionHeaderMiddleware(MiddlewareMixin): + """Middleware to add the InvenTree version header to all responses.""" + + def process_response(self, request, response): + """Add the InvenTree version header to the response.""" + response['X-InvenTree-Version'] = inventreeVersion() + response['X-InvenTree-API'] = inventreeApiVersion() + response['X-InvenTree-Python'] = inventreePythonVersion() + response['X-InvenTree-Installer'] = inventreeInstaller() + return response diff --git a/src/backend/InvenTree/InvenTree/mixins.py b/src/backend/InvenTree/InvenTree/mixins.py index 5dd51c30ca..7d181fb995 100644 --- a/src/backend/InvenTree/InvenTree/mixins.py +++ b/src/backend/InvenTree/InvenTree/mixins.py @@ -6,7 +6,6 @@ from rest_framework import generics, mixins, status from rest_framework.response import Response import data_exporter.mixins -import data_exporter.serializers import importer.mixins from InvenTree.fields import InvenTreeNotesField, OutputConfiguration from InvenTree.helpers import ( @@ -19,7 +18,7 @@ from InvenTree.serializers import FilterableSerializerMixin class CleanMixin: - """Model mixin class which cleans inputs using the Mozilla bleach tools.""" + """Model mixin class which cleans inputs using nh3.""" # Define a list of field names which will *not* be cleaned SAFE_FIELDS = [] @@ -52,16 +51,7 @@ class CleanMixin: return Response(serializer.data) def clean_string(self, field: str, data: str) -> str: - """Clean / sanitize a single input string. - - Note that this function will *allow* orphaned <>& characters, - which would normally be escaped by bleach. - - Nominally, the only thing that will be "cleaned" will be HTML tags - - Ref: https://github.com/mozilla/bleach/issues/192 - - """ + """Clean / sanitize a single input string.""" cleaned = data # By default, newline characters are removed @@ -101,7 +91,7 @@ class CleanMixin: def clean_data(self, data: dict) -> dict: """Clean / sanitize data. - This uses Mozilla's bleach under the hood to disable certain html tags by + This uses nh3 under the hood to disable certain html tags by encoding them - this leads to script tags etc. to not work. The results can be longer then the input; might make some character combinations `ugly`. Prevents XSS on the server-level. @@ -223,20 +213,6 @@ class OutputOptionsMixin: if getattr(cls, 'output_options', None) is not None: schema_for_view_output_options(cls) - def __init__(self) -> None: - """Initialize the mixin. Check that the serializer is compatible.""" - super().__init__() - - # Check that the serializer was defined - if ( - hasattr(self, 'serializer_class') - and isinstance(self.serializer_class, type) - and (not issubclass(self.serializer_class, FilterableSerializerMixin)) - ): - raise Exception( - 'INVE-I2: `OutputOptionsMixin` can only be used with serializers that contain the `FilterableSerializerMixin` mixin' - ) - def get_serializer(self, *args, **kwargs): """Return serializer instance with output options applied.""" request = getattr(self, 'request', None) @@ -250,20 +226,7 @@ class OutputOptionsMixin: context['request'] = request kwargs['context'] = context - serializer = super().get_serializer(*args, **kwargs) - - # Check if the serializer actually can be filtered - makes not much sense to use this mixin without that prerequisite - if isinstance( - serializer, data_exporter.serializers.DataExportOptionsSerializer - ): - # Skip in this instance, special case for determining export options - pass - elif not isinstance(serializer, FilterableSerializerMixin): - raise Exception( - 'INVE-I2: `OutputOptionsMixin` can only be used with serializers that contain the `FilterableSerializerMixin` mixin' - ) - - return serializer + return super().get_serializer(*args, **kwargs) def get_queryset(self): """Return the queryset with output options applied. diff --git a/src/backend/InvenTree/InvenTree/models.py b/src/backend/InvenTree/InvenTree/models.py index dcb22998ee..b6f5692c0a 100644 --- a/src/backend/InvenTree/InvenTree/models.py +++ b/src/backend/InvenTree/InvenTree/models.py @@ -594,7 +594,7 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): parameters.append(parameter) if len(parameters) > 0: - common.models.Parameter.objects.bulk_create(parameters) + common.models.Parameter.objects.bulk_create(parameters, batch_size=250) def get_parameter(self, name: str): """Return a Parameter instance for the given parameter name. @@ -661,7 +661,9 @@ class InvenTreeAttachmentMixin(InvenTreePermissionCheckMixin): Before deleting the model instance, delete any associated attachments. """ - self.attachments.all().delete() + for attachment in list(self.attachments.all()): + attachment.delete() + super().delete(*args, **kwargs) @property @@ -1410,32 +1412,22 @@ def after_failed_task(sender, instance: Task, created: bool, **kwargs): """Callback when a new task failure log is generated.""" from django.conf import settings + from InvenTree.exceptions import log_error + max_attempts = int(settings.Q_CLUSTER.get('max_attempts', 5)) n = instance.attempt_count # Only notify once the maximum number of attempts has been reached if not instance.success and n >= max_attempts: - try: - url = InvenTree.helpers_model.construct_absolute_url( - reverse( - 'admin:django_q_failure_change', kwargs={'object_id': instance.pk} - ) - ) - except (ValueError, NoReverseMatch): - url = '' + # 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 - # Function name - f = instance.func - - notify_staff_users_of_error( - instance, - 'inventree.task_failure', - { - 'failure': instance, - 'name': _('Task Failure'), - 'message': _(f"Background worker task '{f}' failed after {n} attempts"), - 'link': url, - }, + log_error( + 'task_failure', + scope='worker', + error_name='Task Failure', + error_info=f"Task '{instance.pk}' failed after {n} attempts", + error_data=str(instance.result) if instance.result else '', ) @@ -1495,7 +1487,7 @@ class InvenTreeImageMixin(models.Model): def rename_image(self, filename): """Rename the uploaded image file using the IMAGE_RENAME function.""" - return self.IMAGE_RENAME(filename) # type: ignore + return self.IMAGE_RENAME(filename) image = StdImageField( upload_to=rename_image, diff --git a/src/backend/InvenTree/InvenTree/permissions.py b/src/backend/InvenTree/InvenTree/permissions.py index 07006870c5..47af7dabcc 100644 --- a/src/backend/InvenTree/InvenTree/permissions.py +++ b/src/backend/InvenTree/InvenTree/permissions.py @@ -376,7 +376,7 @@ def auth_exempt(view_func): def wrapped_view(*args, **kwargs): return view_func(*args, **kwargs) - wrapped_view.auth_exempt = True # type:ignore[unresolved-attribute] + wrapped_view.auth_exempt = True return wraps(view_func)(wrapped_view) diff --git a/src/backend/InvenTree/InvenTree/ready.py b/src/backend/InvenTree/InvenTree/ready.py index b696ff42fa..8007e30a81 100644 --- a/src/backend/InvenTree/InvenTree/ready.py +++ b/src/backend/InvenTree/InvenTree/ready.py @@ -37,7 +37,9 @@ def isAppLoaded(app_name: str) -> bool: def isInTestMode(): """Returns True if the database is in testing mode.""" - return 'test' in sys.argv or sys.argv[0].endswith('pytest') + return any(x in sys.argv for x in ['test', 'pytest']) or sys.argv[0].endswith( + 'pytest' + ) def isWaitingForDatabase(): @@ -91,25 +93,41 @@ def isCollectingPlugins(): return 'collectplugins' in sys.argv +# This variable is used to cache the result of the isGeneratingSchema function, to prevent multiple executions of the same checks +_IS_GENERATING_SCHEMA: bool | None = None + + +def _setGeneratingSchema(value: bool): + """Set the value of the isGeneratingSchema variable.""" + global _IS_GENERATING_SCHEMA + _IS_GENERATING_SCHEMA = value + return value + + def isGeneratingSchema(): """Return true if schema generation is being executed.""" + global _IS_GENERATING_SCHEMA + + if _IS_GENERATING_SCHEMA is not None: + return _IS_GENERATING_SCHEMA + if isInServerThread() or isInWorkerThread(): - return False + return _setGeneratingSchema(False) if isRunningMigrations() or isRunningBackup() or isRebuildingData(): - return False + return _setGeneratingSchema(False) if isImportingData(): - return False + return _setGeneratingSchema(False) if isInTestMode(): - return False + return _setGeneratingSchema(False) if isWaitingForDatabase(): - return False + return _setGeneratingSchema(False) if isCollectingPlugins(): - return False + return _setGeneratingSchema(False) # Additional set of commands which should not trigger schema generation excluded_commands = [ @@ -119,24 +137,37 @@ def isGeneratingSchema(): 'collectstatic', 'makemessages', 'wait_for_db', + 'list_apps', 'gunicorn', + 'sqlflush', 'qcluster', 'check', 'shell', + 'help', ] if any(cmd in sys.argv for cmd in excluded_commands): - return False + return _setGeneratingSchema(False) - if 'schema' in sys.argv: - return True + included_commands = [ + 'schema', + 'spectactular', + # schema adjacent calls + 'export_settings_definitions', + 'export_tags', + 'export_filters', + 'export_report_context', + ] + + if any(cmd in sys.argv for cmd in included_commands): + return _setGeneratingSchema(True) # This is a very inefficient call - so we only use it as a last resort result = any('drf_spectacular' in frame.filename for frame in inspect.stack()) if not result: # We should only get here if we *are* generating schema - # Raise a warning, so that deevlopers can add extra checks above + # Raise a warning, so that developers can add extra checks above if settings.DEBUG: logger.warning( @@ -144,7 +175,7 @@ def isGeneratingSchema(): ) logger.warning('sys.argv: %s', sys.argv) - return result + return _setGeneratingSchema(result) def isInWorkerThread(): @@ -175,11 +206,46 @@ def isInMainThread(): return not isInWorkerThread() +def readOnlyCommands(): + """Return a list of read-only management commands which should not trigger database writes.""" + return [ + 'help', + 'check', + 'shell', + 'sqlflush', + 'list_apps', + 'wait_for_db', + 'spectactular', + 'makemessages', + 'collectstatic', + 'showmigrations', + 'compilemessages', + ] + + +def isReadOnlyCommand(): + """Return True if the current command is a read-only command, which should not trigger any database writes.""" + if ( + isImportingData() + or isRunningMigrations() + or isRebuildingData() + or isRunningBackup() + ): + return True + + return any(cmd in sys.argv for cmd in readOnlyCommands()) + + def canAppAccessDatabase( allow_test: bool = False, allow_plugins: bool = False, allow_shell: bool = False ): """Returns True if the apps.py file can access database records. + Arguments: + allow_test: If True, override checks and allow database access during testing mode + allow_plugins: If True, override checks and allow database access during plugin loading + allow_shell: If True, override checks and allow database access during shell sessions + There are some circumstances where we don't want the ready function in apps.py to touch the database """ @@ -188,7 +254,7 @@ def canAppAccessDatabase( return False # Prevent database access if we are importing data - if isImportingData(): + if not allow_plugins and isImportingData(): return False # Prevent database access if we are rebuilding data @@ -202,13 +268,13 @@ def canAppAccessDatabase( # If any of the following management commands are being executed, # prevent custom "on load" code from running! excluded_commands = [ - 'check', - 'createsuperuser', - 'wait_for_db', - 'makemessages', 'compilemessages', - 'spectactular', + 'createsuperuser', 'collectstatic', + 'makemessages', + 'spectactular', + 'wait_for_db', + 'check', ] if not allow_shell: diff --git a/src/backend/InvenTree/InvenTree/sanitizer.py b/src/backend/InvenTree/InvenTree/sanitizer.py index ce093b96fe..ea5936c65a 100644 --- a/src/backend/InvenTree/InvenTree/sanitizer.py +++ b/src/backend/InvenTree/InvenTree/sanitizer.py @@ -1,7 +1,66 @@ """Functions to sanitize user input files.""" -from bleach import clean -from bleach.css_sanitizer import CSSSanitizer +import nh3 + +# Allowed CSS properties for SVG sanitization (combines general CSS and SVG-specific properties) +_SVG_ALLOWED_CSS_PROPERTIES = frozenset([ + # General CSS (matching bleach's original ALLOWED_CSS_PROPERTIES) + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', + # SVG-specific CSS (matching bleach's ALLOWED_SVG_PROPERTIES) + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', + 'stroke-width', +]) ALLOWED_ELEMENTS_SVG = [ 'a', @@ -184,6 +243,74 @@ ALLOWED_ATTRIBUTES_SVG = [ 'style', ] +# Default allowlists (matching bleach's original defaults) +# TODO: I do not see us needing a bunch of these but I do not want to introduce a breaking change; we might want to narroy this down with the next breaking change +DEFAULT_TAGS = frozenset([ + 'a', + 'abbr', + 'acronym', + 'b', + 'blockquote', + 'code', + 'em', + 'i', + 'li', + 'ol', + 'strong', + 'ul', +]) +DEAFAULT_ATTRS = {'a': {'href', 'title'}, 'abbr': {'title'}, 'acronym': {'title'}} +DEFAULT_CSS = frozenset([ + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +]) +# TODO: We might want to respect the setting EXTRA_URL_SCHEMES here but that would be breaking +DEFAULT_PROTOCOLS = frozenset(['http', 'https', 'mailto']) + def sanitize_svg( file_data, @@ -206,13 +333,20 @@ def sanitize_svg( if isinstance(file_data, bytes): file_data = file_data.decode('utf-8') - cleaned = clean( + # nh3 requires attributes as dict[str, set[str]]; convert from list (allowed for all elements) + attrs_dict = {elem: set(attributes) for elem in elements} + + cleaned = nh3.clean( file_data, - tags=elements, - attributes=attributes, - strip=strip, + tags=set(elements), + attributes=attrs_dict, + filter_style_properties=_SVG_ALLOWED_CSS_PROPERTIES, strip_comments=strip, - css_sanitizer=CSSSanitizer(), + link_rel=None, ) + # Replace non-breaking spaces with regular spaces to prevent SVG rendering issues + for nbsp in [' ', ' ']: + cleaned = cleaned.replace(nbsp, ' ') + return cleaned diff --git a/src/backend/InvenTree/InvenTree/schema.py b/src/backend/InvenTree/InvenTree/schema.py index 8ec7392130..55fa008349 100644 --- a/src/backend/InvenTree/InvenTree/schema.py +++ b/src/backend/InvenTree/InvenTree/schema.py @@ -55,9 +55,17 @@ class ExtendedAutoSchema(AutoSchema): result_id = super().get_operation_id() # rename bulk actions to deconflict with single action operation_id - if (self.method == 'DELETE' and self.is_bulk_action('BulkDeleteMixin')) or ( - (self.method == 'PUT' or self.method == 'PATCH') - and self.is_bulk_action('BulkUpdateMixin') + if ( + (self.method == 'DELETE' and self.is_bulk_action('BulkDeleteMixin')) + or ( + self.method == 'DELETE' + and self.is_bulk_action('BulkDeleteViewsetMixin') + and self.view.action == 'bulk_delete' + ) + or ( + (self.method == 'PUT' or self.method == 'PATCH') + and self.is_bulk_action('BulkUpdateMixin') + ) ): action = self.method_mapping[self.method.lower()] result_id = result_id.replace(action, 'bulk_' + action) @@ -81,7 +89,11 @@ class ExtendedAutoSchema(AutoSchema): # drf-spectacular doesn't support a body on DELETE endpoints because the semantics are not well-defined and # OpenAPI recommends against it. This allows us to generate a schema that follows existing behavior. - if self.method == 'DELETE' and self.is_bulk_action('BulkDeleteMixin'): + if (self.method == 'DELETE' and self.is_bulk_action('BulkDeleteMixin')) or ( + self.method == 'DELETE' + and getattr(self.view, 'action', None) == 'bulk_delete' + and self.is_bulk_action('BulkDeleteViewsetMixin') + ): original_method = self.method self.method = 'PUT' request_body = self._get_request_body() @@ -329,3 +341,24 @@ def schema_for_view_output_options(view_class): view_class ) return extended_view + + +def exclude_from_schema(klass: type, alternative_path: str) -> type: + """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. + """ + + class LegacyView(klass): + """Dummy doc.""" + + LegacyView.__name__ = klass.__name__ + ' - Legacy' + LegacyView.__doc__ = f'This is a legacy endpoint, retained for backwards compatibility. Consider migrating to the new endpoint under {alternative_path}.' + + # Exclude all default operations from the schema + for operation in ['get', 'post', 'put', 'patch', 'delete']: + if hasattr(klass, operation): + LegacyView = extend_schema_view(**{operation: extend_schema(exclude=True)})( + LegacyView + ) + return LegacyView diff --git a/src/backend/InvenTree/InvenTree/serializers.py b/src/backend/InvenTree/InvenTree/serializers.py index 4bd226a574..3df76e9e3c 100644 --- a/src/backend/InvenTree/InvenTree/serializers.py +++ b/src/backend/InvenTree/InvenTree/serializers.py @@ -1,14 +1,14 @@ """Serializers used in various InvenTree apps.""" -import os from collections import OrderedDict from copy import deepcopy +from dataclasses import dataclass from decimal import Decimal -from typing import Any, Optional +from typing import Optional -from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError as DjangoValidationError +from django.core.files.storage import default_storage from django.db import models from django.db.models import QuerySet from django.utils.translation import gettext_lazy as _ @@ -22,108 +22,250 @@ from rest_framework.exceptions import ValidationError from rest_framework.fields import empty from rest_framework.mixins import ListModelMixin from rest_framework.permissions import SAFE_METHODS -from rest_framework.serializers import DecimalField +from rest_framework.serializers import DecimalField, Serializer from rest_framework.utils import model_meta -from taggit.serializers import TaggitSerializer, TagListSerializerField +from taggit.serializers import TaggitSerializer -import common.models as common_models import InvenTree.ready from common.currency import currency_code_default, currency_code_mappings from InvenTree.fields import InvenTreeRestURLField, InvenTreeURLField from InvenTree.helpers import str2bool from InvenTree.helpers_model import getModelsWithMixin -from .setting.storages import StorageBackends +@dataclass +class OptionalField: + """DataClass used to optionally enable a serializer field. -# region path filtering -class FilterableSerializerField: - """Mixin to mark serializer as filterable. + This is used in conjunction with the `FilterableSerializerMixin` to allow + dynamic inclusion or exclusion of serializer fields at runtime. - This needs to be used in conjunction with `enable_filter` on the serializer field! - """ + Adding OptionalField instances to a serializer class is more "efficient" + than directly adding the field (and later removing it), + as the field is never instantiated unless it is required. - is_filterable = None - is_filterable_vals = {} + Additionally, you can specify prefetch fields which will be applied + to the queryset, *only* if the field is included in the final serializer. - # Options for automatic queryset prefetching - prefetch_fields: Optional[list[str]] = None + This allows for optimization of database queries based only on the requested data. - def __init__(self, *args, **kwargs): - """Initialize the serializer.""" - self.is_filterable = kwargs.pop('is_filterable', None) - self.is_filterable_vals = kwargs.pop('is_filterable_vals', {}) - self.prefetch_fields = kwargs.pop('prefetch_fields', None) - - super().__init__(*args, **kwargs) - - -def enable_filter( - func: Any, - default_include: bool = False, - filter_name: Optional[str] = None, - filter_by_query: bool = True, - prefetch_fields: Optional[list[str]] = None, -): - """Decorator for marking a serializer field as filterable. - - This can be customized by passing in arguments. This only works in conjunction with serializer fields or serializers that contain the `FilterableSerializerField` mixin. - - Args: - func: The serializer field to mark as filterable. Will automatically be passed when used as a decorator. - default_include (bool): If True, the field will be included by default unless explicitly excluded. If False, the field will be excluded by default unless explicitly included. - filter_name (str, optional): The name of the filter parameter to use in the URL. If None, the function name of the (decorated) function will be used. - filter_by_query (bool): If True, also look for filter parameters in the request query parameters. - prefetch_fields (list of str, optional): List of related fields to prefetch when this field is included. This can be used to optimize database queries. - - Returns: - The decorated serializer field, marked as filterable. - """ - # Ensure this function can be actually filtered - if not issubclass(func.__class__, FilterableSerializerField): - raise TypeError( - 'INVE-I2: `enable_filter` can only be applied to serializer fields / serializers that contain the `FilterableSerializerField` mixin!' + Example: + class MySerializer(FilterableSerializerMixin, serializers.ModelSerializer): + my_optional_field = OptionalField( + serializer_class=serializers.CharField, + default_include=False, + filter_name='include_my_field', + serializer_kwargs={ + 'help_text': 'This is an optional field', + 'read_only': True, + }, + prefetch_fields=['related_field'], ) - # Mark the function as filterable - func._kwargs['is_filterable'] = True - func._kwargs['is_filterable_vals'] = { - 'default': default_include, - 'filter_name': filter_name if filter_name else func.field_name, - 'filter_by_query': filter_by_query, - } + """ - # Attach queryset prefetching information - func._kwargs['prefetch_fields'] = prefetch_fields - - return func + serializer_class: Serializer + serializer_kwargs: Optional[dict] = None + default_include: bool = False + filter_name: Optional[str] = None + filter_by_query: bool = True + prefetch_fields: Optional[list[str]] = None class FilterableSerializerMixin: """Mixin that enables filtering of marked fields on a serializer. - Use the `enable_filter` decorator to mark serializer fields as filterable. + Use the `OptionalField` helper class to mark serializer fields as filterable. This introduces overhead during initialization, so only use this mixin when necessary. - If you need to mark a serializer as filterable but it does not contain any filterable fields, set `no_filters = True` to avoid getting an exception that protects against over-application of this mixin. """ - _was_filtered = False - no_filters = False - """If True, do not raise an exception if no filterable fields are found.""" - filter_on_query = True - """If True, also look for filter parameters in the request query parameters.""" + optional_filters: dict = None + fields_to_remove: set = None + optional_fields: set = None + filter_on_query: bool = True def __init__(self, *args, **kwargs): """Initialization routine for the serializer. This gathers and applies filters through kwargs.""" - # add list_serializer_class to meta if not present - reduces duplication - if not isinstance(self, FilterableListSerializer) and ( - not hasattr(self.Meta, 'list_serializer_class') - ): - self.Meta.list_serializer_class = FilterableListSerializer + # Extract some useful context information for later use + context = kwargs.get('context', {}) + self.request = context.get('request', None) or getattr(self, 'request', None) + self.request_query_params = ( + dict(getattr(self.request, 'query_params', {})) if self.request else {} + ) + + self.gather_optional_fields(kwargs) - self.gather_filters(kwargs) super().__init__(*args, **kwargs) - self.do_filtering() + + # Ensure any fields we are *not* using are removed + for field_name in self.fields_to_remove: + self.fields.pop(field_name, None) + + def is_exporting(self) -> bool: + """Determine if we are exporting data.""" + return getattr(self, '_exporting_data', False) + + def is_field_included( + self, field_name: str, field: OptionalField, kwargs: dict + ) -> bool: + """Determine at runtime whether an OptionalField should be included. + + Arguments: + field_name: Name of the field + field: The OptionalField instance + kwargs: The kwargs provided to the serializer instance + + Returns: + True if the field should be included, False otherwise. + + Order of operations: + + - If we are generating the schema, always include the field + - 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 + """ + 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 + cached_value = self.optional_filters.get(field_ref, None) + + if cached_value is not None: + return cached_value + + # First, check kwargs provided to the serializer instance + # We also pop the value to avoid issues with nested serializers + value = kwargs.pop(field_ref, None) + + # We do not want to pop fields while generating the schema + if InvenTree.ready.isGeneratingSchema(): + return True + + if value is not None: + # Cache the value for future reference + self.optional_filters[field_ref] = value + + field_kwargs = field.serializer_kwargs or {} + + # Skip filtering for a write request - all fields should be present for data creation + if method := getattr(self.request, 'method', None): + if method not in SAFE_METHODS and not self.is_exporting(): + return True + else: + # Ignore write_only fields for read requests + if field_kwargs.get('write_only', False): + return False + + # For a top-level serializer, check request query parameters + if self.request and self.filter_on_query and field.filter_by_query: + param_value = self.request.query_params.get(field_ref, None) + + if param_value is not None: + # Convert from list to single value if needed + if type(param_value) == list and len(param_value) == 1: + param_value = param_value[0] + + value = str2bool(param_value) + + # Cache the value for future reference + self.optional_filters[field_ref] = value + + if value is None: + value = field.default_include + + return value + + def find_optional_fields(self): + """Find all optional fields defined on this serializer.""" + optional_fields = {} + + # Walk upwards through the class hierarchy + seen_vars = set() + + for base in self.__class__.__mro__: + for field_name, field in vars(base).items(): + if field_name in seen_vars: + continue + + seen_vars.add(field_name) + + if field and isinstance(field, OptionalField): + optional_fields[field_name] = field + + return optional_fields + + def gather_optional_fields(self, kwargs): + """Determine which optional fields will be included on this serializer. + + Note that there may be instances of OptionalField in the field set, + which need to either be instantiated or removed. + """ + self.optional_filters = {} + self.prefetch_list = set() + self.fields_to_remove = set() + self.optional_fields = set() + + for field_name, field in self.find_optional_fields().items(): + if self.is_field_included(field_name, field, kwargs): + self.optional_fields.add(field_name) + # Add prefetch information + if field.prefetch_fields: + for pf in field.prefetch_fields: + self.prefetch_list.add(pf) + else: + self.fields_to_remove.add(field_name) + + def get_field_names(self, declared_fields, info): + """Remove unused fields before returning field names.""" + field_names = super().get_field_names(declared_fields, info) + + # Add any optional fields which are included + for field_name in self.optional_fields: + if field_name not in field_names: + field_names.append(field_name) + + # Remove any fields which are marked for removal + for field_name in self.fields_to_remove: + if field_name in field_names: + field_names.remove(field_name) + + return field_names + + def build_optional_field(self, field_name: str): + """Build an optional field, based on the provided field name.""" + field = getattr(self, field_name, None) + + if field and isinstance(field, OptionalField): + serializer_kwargs = {**field.serializer_kwargs} or {} + return field.serializer_class, serializer_kwargs + + def build_relational_field(self, field_name, relation_info): + """Handle a special case where an OptionalField shadows a model relation.""" + if field_name in self.optional_fields: + if field := self.build_optional_field(field_name): + return field + + return super().build_relational_field(field_name, relation_info) + + def build_property_field(self, field_name, model_class): + """Handle a special case where an OptionalField shadows a model property.""" + if field_name in self.optional_fields: + if field := self.build_optional_field(field_name): + return field + + return super().build_property_field(field_name, model_class) + + def build_unknown_field(self, field_name, model_class): + """Perform lazy initialization of OptionalFields. + + The DRF framework calls this method when it encounters a field which is not yet initialized. + """ + if field := self.build_optional_field(field_name): + return field + + return super().build_unknown_field(field_name, model_class) def prefetch_queryset(self, queryset: QuerySet) -> QuerySet: """Apply any prefetching to the queryset based on the optionally included fields. @@ -143,157 +285,51 @@ class FilterableSerializerMixin: if getattr(request, '_metadata_requested', False): return queryset - # Gather up the set of simple 'prefetch' fields and functions - prefetch_fields = set() - - filterable_fields = [ - field - for field in self.fields.values() - if getattr(field, 'is_filterable', None) - ] - - for field in filterable_fields: - if prefetch_names := getattr(field, 'prefetch_fields', None): - for pf in prefetch_names: - prefetch_fields.add(pf) - - if prefetch_fields and len(prefetch_fields) > 0: - queryset = queryset.prefetch_related(*list(prefetch_fields)) + if self.prefetch_list and len(self.prefetch_list) > 0: + queryset = queryset.prefetch_related(*list(self.prefetch_list)) return queryset - def gather_filters(self, kwargs) -> None: - """Gather filterable fields through introspection.""" - context = kwargs.get('context', {}) - request = context.get('request', None) or getattr(self, 'request', None) - - # Gather query parameters from the request context - query_params = dict(getattr(request, 'query_params', {})) if request else {} - - # Fast exit if this has already been done or would not have any effect - if getattr(self, '_was_filtered', False) or not hasattr(self, 'fields'): - return - - # Actually gather the filterable fields - # Also see `enable_filter` where` is_filterable and is_filterable_vals are set - self.filter_targets: dict[str, dict] = { - str(k): {'serializer': a, **getattr(a, 'is_filterable_vals', {})} - for k, a in self.fields.items() - if getattr(a, 'is_filterable', None) - } - - # Remove filter args from kwargs to avoid issues with super().__init__ - popped_kwargs = {} # store popped kwargs as a arg might be reused for multiple fields - tgs_vals: dict[str, bool] = {} - for k, v in self.filter_targets.items(): - pop_ref = v['filter_name'] or k - val = kwargs.pop(pop_ref, popped_kwargs.get(pop_ref)) - # Optionally also look in query parameters - # Note that we only do this for a top-level serializer, to avoid issues with nested serializers - if ( - request - and val is None - and self.filter_on_query - and v.get('filter_by_query', True) - ): - val = query_params.pop(pop_ref, None) - - if isinstance(val, list) and len(val) == 1: - val = val[0] - - if val: # Save popped value for reuse - popped_kwargs[pop_ref] = val - tgs_vals[k] = ( - str2bool(val) if isinstance(val, (str, int, float)) else val - ) # Support for various filtering style for backwards compatibility - - self.filter_target_values = tgs_vals - self._was_filtered = True - - # Ensure this mixin is not broadly applied as it is expensive on scale (total CI time increased by 21% when running all coverage tests) - if len(self.filter_targets) == 0 and not self.no_filters: - raise Exception( - 'INVE-I2: No filter targets found in fields, remove `PathScopedMixin`' - ) - - def do_filtering(self) -> None: - """Do the actual filtering.""" - # This serializer might not contain filters or we do not want to pop fields while generating the schema - if ( - not hasattr(self, 'filter_target_values') - or InvenTree.ready.isGeneratingSchema() - ): - return - - is_exporting = getattr(self, '_exporting_data', False) - - # Skip filtering for a write requests - all fields should be present for data creation - if request := self.context.get('request', None): - if method := getattr(request, 'method', None): - if method not in SAFE_METHODS and not is_exporting: - return - - # Throw out fields which are not requested (either by default or explicitly) - for k, v in self.filter_target_values.items(): - # See `enable_filter` where` is_filterable and is_filterable_vals are set - value = v if v is not None else bool(self.filter_targets[k]['default']) - if value is not True: - self.fields.pop(k, None) - - -# special serializers which allow filtering -class FilterableListSerializer( - FilterableSerializerField, FilterableSerializerMixin, serializers.ListSerializer -): - """Custom ListSerializer which allows filtering of fields.""" - - -# special serializer fields which allow filtering -class FilterableListField(FilterableSerializerField, serializers.ListField): - """Custom ListField which allows filtering.""" - - -class FilterableSerializerMethodField( - FilterableSerializerField, serializers.SerializerMethodField -): - """Custom SerializerMethodField which allows filtering.""" - - -class FilterableDateTimeField(FilterableSerializerField, serializers.DateTimeField): - """Custom DateTimeField which allows filtering.""" - - -class FilterableFloatField(FilterableSerializerField, serializers.FloatField): - """Custom FloatField which allows filtering.""" - - -class FilterableCharField(FilterableSerializerField, serializers.CharField): - """Custom CharField which allows filtering.""" - - -class FilterableIntegerField(FilterableSerializerField, serializers.IntegerField): - """Custom IntegerField which allows filtering.""" - - -class FilterableTagListField(FilterableSerializerField, TagListSerializerField): - """Custom TagListSerializerField which allows filtering.""" - - class Meta: - """Empty Meta class.""" - - -# endregion - class EmptySerializer(serializers.Serializer): """Empty serializer for use in testing.""" -class InvenTreeMoneySerializer(FilterableSerializerField, MoneyField): +class TreePathSerializer(serializers.Serializer): + """Serializer field for representing a tree path.""" + + class Meta: + """Metaclass options.""" + + fields = [ + 'pk', + 'name', + # Any fields after this point are optional, and can be included via extra_fields + 'icon', + ] + + def __init__(self, *args, extra_fields: Optional[list[str]] = None, **kwargs): + """Initialize the TreePathSerializer.""" + super().__init__(*args, **kwargs) + + allowed_fields = ['pk', 'name', *(extra_fields or [])] + + if InvenTree.ready.isGeneratingSchema(): + return + + for field in list(self.fields.keys()): + if field not in allowed_fields: + self.fields.pop(field, None) + + pk = serializers.IntegerField(read_only=True) + name = serializers.CharField(read_only=True) + icon = serializers.CharField(required=False, read_only=True, allow_null=True) + + +class InvenTreeMoneySerializer(MoneyField): """Custom serializer for 'MoneyField', which ensures that passed values are numerically valid. Ref: https://github.com/django-money/django-money/blob/master/djmoney/contrib/django_rest_framework/fields.py - This field allows filtering. """ def __init__(self, *args, **kwargs): @@ -480,7 +516,7 @@ class DependentField(serializers.Field): return None -class InvenTreeModelSerializer(FilterableSerializerField, serializers.ModelSerializer): +class InvenTreeModelSerializer(serializers.ModelSerializer): """Inherits the standard Django ModelSerializer class, but also ensures that the underlying model class data are checked on validation.""" # Switch out URLField mapping @@ -689,9 +725,7 @@ class InvenTreeAttachmentSerializerField(serializers.FileField): if not value: return None - if settings.STORAGE_TARGET == StorageBackends.S3: - return str(value.url) - return os.path.join(str(settings.MEDIA_URL), str(value)) + return default_storage.url(str(value)) class InvenTreeImageSerializerField(serializers.ImageField): @@ -705,9 +739,7 @@ class InvenTreeImageSerializerField(serializers.ImageField): if not value: return None - if settings.STORAGE_TARGET == StorageBackends.S3: - return str(value.url) - return os.path.join(str(settings.MEDIA_URL), str(value)) + return default_storage.url(str(value)) class InvenTreeDecimalField(serializers.FloatField): @@ -752,51 +784,6 @@ class NotesFieldMixin: self.fields.pop('notes', None) -class RemoteImageMixin(metaclass=serializers.SerializerMetaclass): - """Mixin class which allows downloading an 'image' from a remote URL. - - Adds the optional, write-only `remote_image` field to the serializer - """ - - def skip_create_fields(self): - """Ensure the 'remote_image' field is skipped when creating a new instance.""" - return ['remote_image'] - - remote_image = serializers.URLField( - required=False, - allow_blank=True, - write_only=True, - label=_('Remote Image'), - help_text=_('URL of remote image file'), - ) - - def validate_remote_image(self, url): - """Perform custom validation for the remote image URL. - - - Attempt to download the image and store it against this object instance - - Catches and re-throws any errors - """ - from InvenTree.helpers_model import download_image_from_url - - if not url: - return - - if not common_models.InvenTreeSetting.get_setting( - 'INVENTREE_DOWNLOAD_FROM_URL' - ): - raise ValidationError( - _('Downloading images from remote URL is not enabled') - ) - - try: - self.remote_image_file = download_image_from_url(url) - except Exception: - self.remote_image_file = None - raise ValidationError(_('Failed to download image from remote URL')) - - return url - - class ContentTypeField(serializers.ChoiceField): """Serializer field which represents a ContentType as 'app_label.model_name'. diff --git a/src/backend/InvenTree/InvenTree/setting/db_backend.py b/src/backend/InvenTree/InvenTree/setting/db_backend.py new file mode 100644 index 0000000000..3cedea07d4 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/setting/db_backend.py @@ -0,0 +1,230 @@ +"""Configuration settings specific to a particular database backend.""" + +from pathlib import Path + +import structlog + +from InvenTree.config import get_boolean_setting, get_config_value, get_setting + +logger = structlog.get_logger('inventree') + + +def get_db_backend(): + """Return the database backend configuration.""" + # For the core database configuration values, we test for UPPERCASE configuration values as a backup, + # due to legacy reasons (original config files were uppercase, + # but we moved to lowercase for consistency with other settings. + + db_config = { + 'ENGINE': get_setting( + 'INVENTREE_DB_ENGINE', 'database.engine', '', typecast=str + ) + or get_config_value('database.ENGINE') + or '', + 'NAME': get_setting('INVENTREE_DB_NAME', 'database.name', '', typecast=str) + or get_config_value('database.NAME') + or '', + 'USER': get_setting('INVENTREE_DB_USER', 'database.user', '', typecast=str) + or get_config_value('database.USER') + or '', + 'PASSWORD': get_setting( + 'INVENTREE_DB_PASSWORD', 'database.password', '', typecast=str + ) + or get_config_value('database.PASSWORD') + or '', + 'HOST': get_setting('INVENTREE_DB_HOST', 'database.host', '', typecast=str) + or get_config_value('database.HOST') + or '', + 'PORT': get_setting('INVENTREE_DB_PORT', 'database.port', '', typecast=str) + or get_config_value('database.PORT') + or '', + 'OPTIONS': get_setting( + 'INVENTREE_DB_OPTIONS', 'database.options', {}, typecast=dict + ) + or get_config_value('database.OPTIONS') + or {}, + } + + # Check for required keys + required_keys = ['ENGINE', 'NAME'] + + for key in required_keys: + if not db_config[key]: + raise ValueError( + f'Missing required database configuration key: INVENTREE_DB_{key}' + ) + + DB_ENGINE = db_config['ENGINE'].lower() + + # Correct common misspelling + if DB_ENGINE == 'sqlite': + DB_ENGINE = 'sqlite3' # pragma: no cover + + if DB_ENGINE in ['sqlite3', 'postgresql', 'mysql']: + # Prepend the required python module string + DB_ENGINE = f'django.db.backends.{DB_ENGINE}' + db_config['ENGINE'] = DB_ENGINE + + if 'sqlite' in DB_ENGINE: + db_name = str(Path(db_config['NAME']).resolve()) + db_config['NAME'] = db_name + + logger.info('DB_ENGINE: %s', DB_ENGINE) + logger.info('DB_NAME: %s', db_config['NAME']) + logger.info('DB_HOST: %s', db_config.get('HOST', "''")) + + # Set testing options for the database + db_config['TEST'] = {'CHARSET': 'utf8'} + + # Set collation option for mysql test database + if 'mysql' in DB_ENGINE: + db_config['TEST']['COLLATION'] = 'utf8_general_ci' # pragma: no cover + + # Specify database specific configuration + set_db_options(DB_ENGINE, db_config['OPTIONS']) + + return db_config + + +def set_db_options(engine: str, db_options: dict): + """Update database options based on the specified database backend. + + Arguments: + engine: The database engine (e.g. 'sqlite3', 'postgresql', etc.) + db_options: The database options dictionary to update + """ + logger.debug('Setting database options: %s', engine) + + if 'postgres' in engine: + set_postgres_options(db_options) + elif 'mysql' in engine: + set_mysql_options(db_options) + elif 'sqlite' in engine: + set_sqlite_options(db_options) + else: + raise ValueError(f'Unknown database engine: {engine}') + + +def set_postgres_options(db_options: dict): + """Set database options specific to postgres backend.""" + from django.db.backends.postgresql.psycopg_any import IsolationLevel + + # Connection timeout + 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) + ) + + # Setup TCP keepalive + # DB server is in the same DC, it should not become unresponsive for + # very long. With the defaults below we wait 5 seconds for the network + # issue to resolve itself. If that doesn't happen, whatever happened + # is probably fatal and no amount of waiting is going to fix it. + # # 0 - TCP Keepalives disabled; 1 - enabled + if 'keepalives' not in db_options: + db_options['keepalives'] = int( + get_setting('INVENTREE_DB_TCP_KEEPALIVES', 'database.tcp_keepalives', 1) + ) + + # Seconds after connection is idle to send keep alive + if 'keepalives_idle' not in db_options: + db_options['keepalives_idle'] = int( + get_setting( + 'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 1 + ) + ) + + # Seconds after missing ACK to send another keep alive + if 'keepalives_interval' not in db_options: + db_options['keepalives_interval'] = int( + get_setting( + 'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL', + 'database.tcp_keepalives_interval', + '1', + ) + ) + + # Number of missing ACKs before we close the connection + if 'keepalives_count' not in db_options: + db_options['keepalives_count'] = int( + get_setting( + 'INVENTREE_DB_TCP_KEEPALIVES_COUNT', + 'database.tcp_keepalives_count', + '5', + ) + ) + + # # 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"), + + # Postgres's default isolation level is Read Committed which is + # normally fine, but most developers think the database server is + # actually going to do Serializable type checks on the queries to + # protect against simultaneous changes. + # https://www.postgresql.org/docs/devel/transaction-iso.html + # https://docs.djangoproject.com/en/3.2/ref/databases/#isolation-level + if 'isolation_level' not in db_options: + serializable = get_boolean_setting( + 'INVENTREE_DB_ISOLATION_SERIALIZABLE', 'database.serializable', False + ) + db_options['isolation_level'] = ( + IsolationLevel.SERIALIZABLE + if serializable + else IsolationLevel.READ_COMMITTED + ) + + +def set_mysql_options(db_options: dict): + """Set database options specific to mysql backend.""" + # TODO TCP time outs and keepalives + + # MariaDB's default isolation level is Repeatable Read which is + # normally fine, but most developers think the database server is + # actually going to Serializable type checks on the queries to + # protect against simultaneous changes. + # https://mariadb.com/kb/en/mariadb-transactions-and-isolation-levels-for-sql-server-users/#changing-the-isolation-level + # https://docs.djangoproject.com/en/3.2/ref/databases/#mysql-isolation-level + if 'isolation_level' not in db_options: + serializable = get_boolean_setting( + 'INVENTREE_DB_ISOLATION_SERIALIZABLE', 'database.serializable', False + ) + db_options['isolation_level'] = ( + 'serializable' if serializable else 'read committed' + ) + + +def set_sqlite_options(db_options: dict): + """Set database options specific to sqlite backend. + + References: + - https://docs.djangoproject.com/en/5.0/ref/databases/#sqlite-notes + - https://docs.djangoproject.com/en/6.0/ref/databases/#database-is-locked-errors + """ + import InvenTree.ready + + # Specify minimum timeout behavior for SQLite connections + if 'timeout' not in db_options: + db_options['timeout'] = int( + get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10) + ) + + # Specify the transaction mode for the database + # For the backend worker thread, IMMEDIATE mode is used, + # it has been determined to provide better protection against database locks in the worker thread + db_options['transaction_mode'] = ( + 'IMMEDIATE' if InvenTree.ready.isInWorkerThread() else 'DEFERRED' + ) + + # SQLite's default isolation level is Serializable due to SQLite's + # single writer implementation. Presumably as a result of this, it is + # not possible to implement any lower isolation levels in SQLite. + # https://www.sqlite.org/isolation.html + + if get_boolean_setting('INVENTREE_DB_WAL_MODE', 'database.wal_mode', True): + # Specify that we want to use Write-Ahead Logging (WAL) mode for SQLite databases, as this allows for better concurrency and performance + db_options['init_command'] = 'PRAGMA journal_mode=WAL;' diff --git a/src/backend/InvenTree/InvenTree/setting/ldap.py b/src/backend/InvenTree/InvenTree/setting/ldap.py new file mode 100644 index 0000000000..6e6f57989f --- /dev/null +++ b/src/backend/InvenTree/InvenTree/setting/ldap.py @@ -0,0 +1,139 @@ +"""Configuration of LDAP support for InvenTree.""" + +from InvenTree.config import get_boolean_setting, get_setting + + +def get_ldap_config(debug: bool = False) -> dict: + """Return a dictionary of LDAP configuration settings. + + 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] + + # get global options from dict and use ldap.OPT_* as keys and values + global_options_dict = get_setting( + 'INVENTREE_LDAP_GLOBAL_OPTIONS', + 'ldap.global_options', + default_value=None, + typecast=dict, + ) + + global_options = {} + + for k, v in global_options_dict.items(): + # keys are always ldap.OPT_* constants + k_attr = getattr(ldap, k, None) + if not k.startswith('OPT_') or k_attr is None: + print(f"[LDAP] ldap.global_options, key '{k}' not found, skipping...") + continue + + # values can also be other strings, e.g. paths + v_attr = v + if v.startswith('OPT_'): + v_attr = getattr(ldap, v, None) + + if v_attr is None: + print(f"[LDAP] ldap.global_options, value key '{v}' not found, skipping...") + continue + + global_options[k_attr] = v_attr + + if debug: + print('[LDAP] ldap.global_options =', global_options) + + group_type_class = get_setting( + 'INVENTREE_LDAP_GROUP_TYPE_CLASS', + 'ldap.group_type_class', + 'GroupOfUniqueNamesType', + str, + ) + + group_type_class_args = get_setting( + 'INVENTREE_LDAP_GROUP_TYPE_CLASS_ARGS', 'ldap.group_type_class_args', [], list + ) + + group_type_class_kwargs = get_setting( + 'INVENTREE_LDAP_GROUP_TYPE_CLASS_KWARGS', + 'ldap.group_type_class_kwargs', + {'name_attr': 'cn'}, + dict, + ) + + group_object_class = get_setting( + 'INVENTREE_LDAP_GROUP_OBJECT_CLASS', + 'ldap.group_object_class', + 'groupOfUniqueNames', + str, + ) + + ldap_config = { + 'AUTH_LDAP_GLOBAL_OPTIONS': global_options, + 'AUTH_LDAP_SERVER_URI': get_setting( + 'INVENTREE_LDAP_SERVER_URI', 'ldap.server_uri' + ), + 'AUTH_LDAP_START_TLS': get_boolean_setting( + 'INVENTREE_LDAP_START_TLS', 'ldap.start_tls', False + ), + 'AUTH_LDAP_BIND_DN': get_setting('INVENTREE_LDAP_BIND_DN', 'ldap.bind_dn'), + 'AUTH_LDAP_BIND_PASSWORD': get_setting( + 'INVENTREE_LDAP_BIND_PASSWORD', 'ldap.bind_password' + ), + 'AUTH_LDAP_USER_SEARCH': django_auth_ldap.config.LDAPSearch( + get_setting('INVENTREE_LDAP_SEARCH_BASE_DN', 'ldap.search_base_dn'), + ldap.SCOPE_SUBTREE, + str( + get_setting( + 'INVENTREE_LDAP_SEARCH_FILTER_STR', + 'ldap.search_filter_str', + '(uid= %(user)s)', + ) + ), + ), + 'AUTH_LDAP_USER_DN_TEMPLATE': get_setting( + 'INVENTREE_LDAP_USER_DN_TEMPLATE', 'ldap.user_dn_template' + ), + 'AUTH_LDAP_USER_ATTR_MAP': get_setting( + 'INVENTREE_LDAP_USER_ATTR_MAP', + 'ldap.user_attr_map', + {'first_name': 'givenName', 'last_name': 'sn', 'email': 'mail'}, + dict, + ), + 'AUTH_LDAP_ALWAYS_UPDATE_USER': get_boolean_setting( + 'INVENTREE_LDAP_ALWAYS_UPDATE_USER', 'ldap.always_update_user', True + ), + 'AUTH_LDAP_CACHE_TIMEOUT': get_setting( + 'INVENTREE_LDAP_CACHE_TIMEOUT', 'ldap.cache_timeout', 3600, int + ), + 'AUTH_LDAP_MIRROR_GROUPS': get_boolean_setting( + 'INVENTREE_LDAP_MIRROR_GROUPS', 'ldap.mirror_groups', False + ), + 'AUTH_LDAP_GROUP_OBJECT_CLASS': group_object_class, + 'AUTH_LDAP_GROUP_SEARCH': django_auth_ldap.config.LDAPSearch( + get_setting('INVENTREE_LDAP_GROUP_SEARCH', 'ldap.group_search'), + ldap.SCOPE_SUBTREE, + f'(objectClass={group_object_class})', + ), + 'AUTH_LDAP_GROUP_TYPE_CLASS': group_type_class, + 'AUTH_LDAP_GROUP_TYPE_CLASS_ARGS': [*group_type_class_args], + 'AUTH_LDAP_GROUP_TYPE_CLASS_KWARGS': {**group_type_class_kwargs}, + 'AUTH_LDAP_GROUP_TYPE': getattr(django_auth_ldap.config, group_type_class)( + *group_type_class_args, **group_type_class_kwargs + ), + 'AUTH_LDAP_REQUIRE_GROUP': get_setting( + 'INVENTREE_LDAP_REQUIRE_GROUP', 'ldap.require_group' + ), + 'AUTH_LDAP_DENY_GROUP': get_setting( + 'INVENTREE_LDAP_DENY_GROUP', 'ldap.deny_group' + ), + 'AUTH_LDAP_USER_FLAGS_BY_GROUP': get_setting( + 'INVENTREE_LDAP_USER_FLAGS_BY_GROUP', + 'ldap.user_flags_by_group', + default_value=None, + typecast=dict, + ), + 'AUTH_LDAP_FIND_GROUP_PERMS': True, + } + + return ldap_config diff --git a/src/backend/InvenTree/InvenTree/setting/tracing.py b/src/backend/InvenTree/InvenTree/setting/tracing.py new file mode 100644 index 0000000000..59a667b71d --- /dev/null +++ b/src/backend/InvenTree/InvenTree/setting/tracing.py @@ -0,0 +1,61 @@ +"""Start-up configuration options for InvenTree tracing integrations.""" + +import structlog + +from InvenTree.config import get_boolean_setting, get_setting +from InvenTree.tracing import setup_instruments, setup_tracing + +logger = structlog.get_logger('inventree') + + +def configure_tracing(db_engine: str, enabled: bool, tags: dict) -> dict: + """Configure tracing integrations for InvenTree. + + Arguments: + db_engine: The database engine being used + enabled: Whether tracing is enabled + tags: A dictionary of tags to be included in tracing spans, with keys prefixed by + """ + endpoint = get_setting('INVENTREE_TRACING_ENDPOINT', 'tracing.endpoint', None) + headers = ( + get_setting('INVENTREE_TRACING_HEADERS', 'tracing.headers', None, typecast=dict) + or {} + ) + + if enabled and endpoint: + logger.info('Tracing enabled with endpoint: %s', endpoint) + + TRACING_DETAILS = { + 'endpoint': endpoint, + 'headers': headers, + 'resources_input': { + **{'inventree.env.' + k: v for k, v in tags.items()}, + **get_setting( + 'INVENTREE_TRACING_RESOURCES', + 'tracing.resources', + default_value=None, + typecast=dict, + ), + }, + 'console': get_boolean_setting( + 'INVENTREE_TRACING_CONSOLE', 'tracing.console', False + ), + 'auth': get_setting( + 'INVENTREE_TRACING_AUTH', 'tracing.auth', default_value=None, typecast=dict + ), + 'is_http': get_setting('INVENTREE_TRACING_IS_HTTP', 'tracing.is_http', True), + 'append_http': get_boolean_setting( + 'INVENTREE_TRACING_APPEND_HTTP', 'tracing.append_http', True + ), + } + + if not enabled: + return None + + if endpoint: + setup_tracing(**TRACING_DETAILS) + setup_instruments(db_engine) + else: + logger.warning('OpenTelemetry tracing not enabled because endpoint is not set') + + return TRACING_DETAILS diff --git a/src/backend/InvenTree/InvenTree/setting/worker.py b/src/backend/InvenTree/InvenTree/setting/worker.py new file mode 100644 index 0000000000..bef1380bd2 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/setting/worker.py @@ -0,0 +1,88 @@ +"""Configuration settings for the InvenTree background worker process.""" + +import sys + +from InvenTree.config import get_setting + + +def get_worker_config( + db_engine: str, + global_cache: bool = False, + sentry_dsn: str = '', + debug: bool = False, +) -> dict: + """Return a dictionary of configuration settings for the background worker. + + Arguments: + db_engine: The database engine being used (e.g. 'sqlite', 'postgresql', 'mysql') + global_cache: Whether a global redis cache is enabled + sentry_dsn: The DSN for sentry.io integration (if enabled) + debug: Whether the application is running in debug mode + + Ref: https://django-q2.readthedocs.io/en/master/configure.html + """ + BACKGROUND_WORKER_TIMEOUT = int( + get_setting('INVENTREE_BACKGROUND_TIMEOUT', 'background.timeout', 90) + ) + + # Set the retry time for background workers to be slightly longer than the worker timeout, to ensure that workers have time to timeout before being retried + BACKGROUND_WORKER_RETRY = max( + int(get_setting('INVENTREE_BACKGROUND_RETRY', 'background.retry', 300)), + BACKGROUND_WORKER_TIMEOUT + 120, + ) + + BACKGROUND_WORKER_ATTEMPTS = int( + get_setting('INVENTREE_BACKGROUND_MAX_ATTEMPTS', 'background.max_attempts', 5) + ) + + # Prevent running multiple background workers if global cache is disabled + # This is to prevent scheduling conflicts due to the lack of a shared cache + BACKGROUND_WORKER_COUNT = int( + get_setting('INVENTREE_BACKGROUND_WORKERS', 'background.workers', 4) + ) + + # If global cache is disabled, we cannot run multiple background workers + if not global_cache: + BACKGROUND_WORKER_COUNT = 1 + + # If running with SQLite, limit background worker threads to 1 to prevent database locking issues + if 'sqlite' in db_engine: + BACKGROUND_WORKER_COUNT = 1 + + # Check if '--sync' was passed in the command line + if '--sync' in sys.argv and '--noreload' in sys.argv and debug: + SYNC_TASKS = True + else: + SYNC_TASKS = False + + # Clean up sys.argv so Django doesn't complain about an unknown argument + if SYNC_TASKS: + sys.argv.remove('--sync') + + # django-q background worker configuration + config = { + 'name': 'InvenTree', + 'label': 'Background Tasks', + 'workers': BACKGROUND_WORKER_COUNT, + 'timeout': BACKGROUND_WORKER_TIMEOUT, + 'retry': BACKGROUND_WORKER_RETRY, + 'max_attempts': BACKGROUND_WORKER_ATTEMPTS, + 'save_limit': 1000, + 'queue_limit': 50, + 'catch_up': False, + 'bulk': 10, + 'orm': 'default', + 'cache': 'default', + 'sync': SYNC_TASKS, + 'poll': 1.5, + } + + if global_cache: + # If using external redis cache, make the cache the broker for Django Q + config['django_redis'] = 'worker' + + if sentry_dsn: + # If sentry is enabled, configure django-q to report errors to sentry + config['error_reporter'] = {'sentry': {'dsn': sentry_dsn}} + + return config diff --git a/src/backend/InvenTree/InvenTree/settings.py b/src/backend/InvenTree/InvenTree/settings.py index 0d8831f365..3aa32669be 100644 --- a/src/backend/InvenTree/InvenTree/settings.py +++ b/src/backend/InvenTree/InvenTree/settings.py @@ -12,7 +12,6 @@ database setup in this file. import logging import os import sys -from pathlib import Path from typing import Optional from zoneinfo import ZoneInfo, ZoneInfoNotFoundError @@ -33,7 +32,16 @@ from InvenTree.version import checkMinPythonVersion, inventreeCommitHash from users.oauth2_scopes import oauth2_scopes from . import config -from .setting import locales, markdown, spectacular, storages +from .setting import ( + db_backend, + ldap, + locales, + markdown, + spectacular, + storages, + tracing, + worker, +) try: import django_stubs_ext @@ -81,6 +89,8 @@ DEBUG = get_boolean_setting('INVENTREE_DEBUG', 'debug', False) # Internal flag to determine if we are running in docker mode DOCKER = get_boolean_setting('INVENTREE_DOCKER', default_value=False) +AUTO_UPDATE = get_boolean_setting('INVENTREE_AUTO_UPDATE', 'auto_update', False) + # Configure logging settings LOG_LEVEL = get_setting('INVENTREE_LOG_LEVEL', 'log_level', 'WARNING') JSON_LOG = get_boolean_setting('INVENTREE_JSON_LOG', 'json_log', False) @@ -194,10 +204,18 @@ PLUGINS_MANDATORY = get_setting( 'INVENTREE_PLUGINS_MANDATORY', 'plugins_mandatory', typecast=list, default_value=[] ) +if PLUGINS_MANDATORY: + logger.info('Mandatory plugins: %s', PLUGINS_MANDATORY) + PLUGINS_INSTALL_DISABLED = get_boolean_setting( 'INVENTREE_PLUGIN_NOINSTALL', 'plugin_noinstall', False ) +if not PLUGINS_ENABLED: + PLUGINS_INSTALL_DISABLED = ( + True # If plugins are disabled, also disable installation + ) + PLUGIN_FILE = config.get_plugin_file() # Plugin test settings @@ -214,9 +232,7 @@ PLUGIN_TESTING_EVENTS_ASYNC = False # Flag if events are tested asynchronously PLUGIN_TESTING_RELOAD = False # Flag if plugin reloading is in testing (check_reload) # Plugin development settings -PLUGIN_DEV_SLUG = ( - get_setting('INVENTREE_PLUGIN_DEV_SLUG', 'plugin_dev.slug') if DEBUG else None -) +PLUGIN_DEV_SLUG = get_setting('INVENTREE_PLUGIN_DEV_SLUG', 'plugin_dev.slug') PLUGIN_DEV_HOST = get_setting( 'INVENTREE_PLUGIN_DEV_HOST', 'plugin_dev.host', 'http://localhost:5174' @@ -372,13 +388,17 @@ MIDDLEWARE = CONFIG.get( 'InvenTree.middleware.InvenTreeRequestCacheMiddleware', # Request caching 'InvenTree.middleware.InvenTreeHostSettingsMiddleware', # Ensuring correct hosting/security settings 'django_structlog.middlewares.RequestMiddleware', # Structured logging + 'InvenTree.middleware.InvenTreeVersionHeaderMiddleware', ], ) # In DEBUG mode, add support for django-silk # Ref: https://silk.readthedocs.io/en/latest/ -DJANGO_SILK_ENABLED = DEBUG and get_boolean_setting( # pragma: no cover - 'INVENTREE_DEBUG_SILK', 'debug_silk', False +DJANGO_SILK_ENABLED = ( + get_boolean_setting( # pragma: no cover + 'INVENTREE_DEBUG_SILK', 'debug_silk', False + ) + and DEBUG ) if DJANGO_SILK_ENABLED: # pragma: no cover @@ -392,8 +412,11 @@ if DJANGO_SILK_ENABLED: # pragma: no cover # In DEBUG mode, add support for django-querycount # Ref: https://github.com/bradmontgomery/django-querycount -if DEBUG and get_boolean_setting( # pragma: no cover - 'INVENTREE_DEBUG_QUERYCOUNT', 'debug_querycount', False +if ( + get_boolean_setting( # pragma: no cover + 'INVENTREE_DEBUG_QUERYCOUNT', 'debug_querycount', False + ) + and DEBUG ): MIDDLEWARE.append('querycount.middleware.QueryCountMiddleware') logger.debug('Running with debug_querycount middleware enabled') @@ -428,14 +451,14 @@ AUTHENTICATION_BACKENDS = ( # LDAP support LDAP_AUTH = get_boolean_setting('INVENTREE_LDAP_ENABLED', 'ldap.enabled', False) -if LDAP_AUTH: # pragma: no cover - import django_auth_ldap.config # type: ignore[unresolved-import] - import ldap # type: ignore[unresolved-import] +LDAP_DEBUG = ( + get_boolean_setting('INVENTREE_LDAP_DEBUG', 'ldap.debug', False) and LDAP_AUTH +) +if LDAP_AUTH: # pragma: no cover AUTHENTICATION_BACKENDS.append('django_auth_ldap.backend.LDAPBackend') # debug mode to troubleshoot configuration - LDAP_DEBUG = get_boolean_setting('INVENTREE_LDAP_DEBUG', 'ldap.debug', False) if LDAP_DEBUG: if 'loggers' not in LOGGING: LOGGING['loggers'] = {} @@ -444,113 +467,10 @@ if LDAP_AUTH: # pragma: no cover 'handlers': DEFAULT_LOG_HANDLER, } - # get global options from dict and use ldap.OPT_* as keys and values - global_options_dict = get_setting( - 'INVENTREE_LDAP_GLOBAL_OPTIONS', - 'ldap.global_options', - default_value=None, - typecast=dict, - ) - global_options = {} - for k, v in global_options_dict.items(): - # keys are always ldap.OPT_* constants - k_attr = getattr(ldap, k, None) - if not k.startswith('OPT_') or k_attr is None: - print(f"[LDAP] ldap.global_options, key '{k}' not found, skipping...") - continue + # Determine LDAP settings + ldap_settings = ldap.get_ldap_config(debug=LDAP_DEBUG) + globals().update(ldap_settings) - # values can also be other strings, e.g. paths - v_attr = v - if v.startswith('OPT_'): - v_attr = getattr(ldap, v, None) - - if v_attr is None: - print(f"[LDAP] ldap.global_options, value key '{v}' not found, skipping...") - continue - - global_options[k_attr] = v_attr - AUTH_LDAP_GLOBAL_OPTIONS = global_options - if LDAP_DEBUG: - print('[LDAP] ldap.global_options =', global_options) - - AUTH_LDAP_SERVER_URI = get_setting('INVENTREE_LDAP_SERVER_URI', 'ldap.server_uri') - AUTH_LDAP_START_TLS = get_boolean_setting( - 'INVENTREE_LDAP_START_TLS', 'ldap.start_tls', False - ) - AUTH_LDAP_BIND_DN = get_setting('INVENTREE_LDAP_BIND_DN', 'ldap.bind_dn') - AUTH_LDAP_BIND_PASSWORD = get_setting( - 'INVENTREE_LDAP_BIND_PASSWORD', 'ldap.bind_password' - ) - AUTH_LDAP_USER_SEARCH = django_auth_ldap.config.LDAPSearch( - get_setting('INVENTREE_LDAP_SEARCH_BASE_DN', 'ldap.search_base_dn'), - ldap.SCOPE_SUBTREE, # type: ignore[unresolved-attribute] - str( - get_setting( - 'INVENTREE_LDAP_SEARCH_FILTER_STR', - 'ldap.search_filter_str', - '(uid= %(user)s)', - ) - ), - ) - AUTH_LDAP_USER_DN_TEMPLATE = get_setting( - 'INVENTREE_LDAP_USER_DN_TEMPLATE', 'ldap.user_dn_template' - ) - AUTH_LDAP_USER_ATTR_MAP = get_setting( - 'INVENTREE_LDAP_USER_ATTR_MAP', - 'ldap.user_attr_map', - {'first_name': 'givenName', 'last_name': 'sn', 'email': 'mail'}, - dict, - ) - AUTH_LDAP_ALWAYS_UPDATE_USER = get_boolean_setting( - 'INVENTREE_LDAP_ALWAYS_UPDATE_USER', 'ldap.always_update_user', True - ) - AUTH_LDAP_CACHE_TIMEOUT = get_setting( - 'INVENTREE_LDAP_CACHE_TIMEOUT', 'ldap.cache_timeout', 3600, int - ) - - AUTH_LDAP_MIRROR_GROUPS = get_boolean_setting( - 'INVENTREE_LDAP_MIRROR_GROUPS', 'ldap.mirror_groups', False - ) - AUTH_LDAP_GROUP_OBJECT_CLASS = get_setting( - 'INVENTREE_LDAP_GROUP_OBJECT_CLASS', - 'ldap.group_object_class', - 'groupOfUniqueNames', - str, - ) - AUTH_LDAP_GROUP_SEARCH = django_auth_ldap.config.LDAPSearch( - get_setting('INVENTREE_LDAP_GROUP_SEARCH', 'ldap.group_search'), - ldap.SCOPE_SUBTREE, # type: ignore[unresolved-attribute] - f'(objectClass={AUTH_LDAP_GROUP_OBJECT_CLASS})', - ) - AUTH_LDAP_GROUP_TYPE_CLASS = get_setting( - 'INVENTREE_LDAP_GROUP_TYPE_CLASS', - 'ldap.group_type_class', - 'GroupOfUniqueNamesType', - str, - ) - AUTH_LDAP_GROUP_TYPE_CLASS_ARGS = get_setting( - 'INVENTREE_LDAP_GROUP_TYPE_CLASS_ARGS', 'ldap.group_type_class_args', [], list - ) - AUTH_LDAP_GROUP_TYPE_CLASS_KWARGS = get_setting( - 'INVENTREE_LDAP_GROUP_TYPE_CLASS_KWARGS', - 'ldap.group_type_class_kwargs', - {'name_attr': 'cn'}, - dict, - ) - AUTH_LDAP_GROUP_TYPE = getattr(django_auth_ldap.config, AUTH_LDAP_GROUP_TYPE_CLASS)( - *AUTH_LDAP_GROUP_TYPE_CLASS_ARGS, **AUTH_LDAP_GROUP_TYPE_CLASS_KWARGS - ) - AUTH_LDAP_REQUIRE_GROUP = get_setting( - 'INVENTREE_LDAP_REQUIRE_GROUP', 'ldap.require_group' - ) - AUTH_LDAP_DENY_GROUP = get_setting('INVENTREE_LDAP_DENY_GROUP', 'ldap.deny_group') - AUTH_LDAP_USER_FLAGS_BY_GROUP = get_setting( - 'INVENTREE_LDAP_USER_FLAGS_BY_GROUP', - 'ldap.user_flags_by_group', - default_value=None, - typecast=dict, - ) - AUTH_LDAP_FIND_GROUP_PERMS = True # Allow secure http developer server in debug mode if DEBUG: @@ -633,207 +553,11 @@ Configure the database backend based on the user-specified values. logger.debug('Configuring database backend:') -# Extract database configuration from the config.yaml file -db_config = CONFIG.get('database', None) if CONFIG else None +# Load database configuration from the config file and environment variables +database = db_backend.get_db_backend() +DB_ENGINE = database['ENGINE'] -if not db_config: - db_config = {} - -# Environment variables take preference over config file! - -db_keys = ['ENGINE', 'NAME', 'USER', 'PASSWORD', 'HOST', 'PORT'] - -for key in db_keys: - # First, check the environment variables - env_key = f'INVENTREE_DB_{key}' - env_var = os.environ.get(env_key, None) - - if env_var: - # Make use PORT is int - if key == 'PORT': - try: - env_var = int(env_var) - except ValueError: - logger.exception('Invalid number for %s: %s', env_key, env_var) - # Override configuration value - db_config[key] = env_var - -# Check that required database configuration options are specified -required_keys = ['ENGINE', 'NAME'] - -# Ensure all database keys are upper case -db_config = {key.upper(): value for key, value in db_config.items()} - -for key in required_keys: - if key not in db_config: # pragma: no cover - error_msg = ( - f'Missing required database configuration value `INVENTREE_DB_{key}`' - ) - logger.error(error_msg) - - print('Error: ' + error_msg) - sys.exit(-1) - -""" -Special considerations for the database 'ENGINE' setting. -It can be specified in config.yaml (or envvar) as either (for example): -- sqlite3 -- django.db.backends.sqlite3 -- django.db.backends.postgresql -""" - -DB_ENGINE = db_config['ENGINE'].lower() - -# Correct common misspelling -if DB_ENGINE == 'sqlite': - DB_ENGINE = 'sqlite3' # pragma: no cover - -if DB_ENGINE in ['sqlite3', 'postgresql', 'mysql']: - # Prepend the required python module string - DB_ENGINE = f'django.db.backends.{DB_ENGINE}' - db_config['ENGINE'] = DB_ENGINE - -db_name = db_config['NAME'] -db_host = db_config.get('HOST', "''") - -if 'sqlite' in DB_ENGINE: - db_name = str(Path(db_name).resolve()) - db_config['NAME'] = db_name - -logger.info('DB_ENGINE: %s', DB_ENGINE) -logger.info('DB_NAME: %s', db_name) -logger.info('DB_HOST: %s', db_host) - -""" -In addition to base-level database configuration, we may wish to specify specific options to the database backend -Ref: https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-OPTIONS -""" - -# 'OPTIONS' or 'options' can be specified in config.yaml -# Set useful sensible timeouts for a transactional webserver to communicate -# with its database server, that is, if the webserver is having issues -# connecting to the database server (such as a replica failover) don't sit and -# wait for possibly an hour or more, just tell the client something went wrong -# and let the client retry when they want to. -db_options = db_config.get('OPTIONS', db_config.get('options')) - -if db_options is None: - db_options = {} - -# Specific options for postgres backend -if 'postgres' in DB_ENGINE: # pragma: no cover - from django.db.backends.postgresql.psycopg_any import ( # type: ignore[unresolved-import] - IsolationLevel, - ) - - # Connection timeout - 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) - ) - - # Setup TCP keepalive - # DB server is in the same DC, it should not become unresponsive for - # very long. With the defaults below we wait 5 seconds for the network - # issue to resolve itself. It it that doesn't happen whatever happened - # is probably fatal and no amount of waiting is going to fix it. - # # 0 - TCP Keepalives disabled; 1 - enabled - if 'keepalives' not in db_options: - db_options['keepalives'] = int( - get_setting('INVENTREE_DB_TCP_KEEPALIVES', 'database.tcp_keepalives', 1) - ) - - # Seconds after connection is idle to send keep alive - if 'keepalives_idle' not in db_options: - db_options['keepalives_idle'] = int( - get_setting( - 'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 1 - ) - ) - - # Seconds after missing ACK to send another keep alive - if 'keepalives_interval' not in db_options: - db_options['keepalives_interval'] = int( - get_setting( - 'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL', - 'database.tcp_keepalives_internal', - '1', - ) - ) - - # Number of missing ACKs before we close the connection - if 'keepalives_count' not in db_options: - db_options['keepalives_count'] = int( - get_setting( - 'INVENTREE_DB_TCP_KEEPALIVES_COUNT', - 'database.tcp_keepalives_count', - '5', - ) - ) - - # # 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"), - - # Postgres's default isolation level is Read Committed which is - # normally fine, but most developers think the database server is - # actually going to do Serializable type checks on the queries to - # protect against simultaneous changes. - # https://www.postgresql.org/docs/devel/transaction-iso.html - # https://docs.djangoproject.com/en/3.2/ref/databases/#isolation-level - if 'isolation_level' not in db_options: - serializable = get_boolean_setting( - 'INVENTREE_DB_ISOLATION_SERIALIZABLE', 'database.serializable', False - ) - db_options['isolation_level'] = ( - IsolationLevel.SERIALIZABLE - if serializable - else IsolationLevel.READ_COMMITTED - ) - -# Specific options for MySql / MariaDB backend -elif 'mysql' in DB_ENGINE: # pragma: no cover - # TODO TCP time outs and keepalives - - # MariaDB's default isolation level is Repeatable Read which is - # normally fine, but most developers think the database server is - # actually going to Serializable type checks on the queries to - # protect against siumltaneous changes. - # https://mariadb.com/kb/en/mariadb-transactions-and-isolation-levels-for-sql-server-users/#changing-the-isolation-level - # https://docs.djangoproject.com/en/3.2/ref/databases/#mysql-isolation-level - if 'isolation_level' not in db_options: - serializable = get_boolean_setting( - 'INVENTREE_DB_ISOLATION_SERIALIZABLE', 'database.serializable', False - ) - db_options['isolation_level'] = ( - 'serializable' if serializable else 'read committed' - ) - -# Specific options for sqlite backend -elif 'sqlite' in DB_ENGINE: - # TODO: Verify timeouts are not an issue because no network is involved for SQLite - - # SQLite's default isolation level is Serializable due to SQLite's - # single writer implementation. Presumably as a result of this, it is - # not possible to implement any lower isolation levels in SQLite. - # https://www.sqlite.org/isolation.html - pass - -# Provide OPTIONS dict back to the database configuration dict -db_config['OPTIONS'] = db_options - -# Set testing options for the database -db_config['TEST'] = {'CHARSET': 'utf8'} - -# Set collation option for mysql test database -if 'mysql' in DB_ENGINE: - db_config['TEST']['COLLATION'] = 'utf8_general_ci' # pragma: no cover - -DATABASES = {'default': db_config} +DATABASES = {'default': database} # login settings REMOTE_LOGIN = get_boolean_setting( @@ -867,111 +591,28 @@ if SENTRY_ENABLED and SENTRY_DSN and not TESTING: # pragma: no cover init_sentry(SENTRY_DSN, SENTRY_SAMPLE_RATE, inventree_tags) # OpenTelemetry tracing -TRACING_ENABLED = get_boolean_setting( - 'INVENTREE_TRACING_ENABLED', 'tracing.enabled', False +TRACING_ENABLED = ( + get_boolean_setting('INVENTREE_TRACING_ENABLED', 'tracing.enabled', False) + and not isRunningBackup() ) -TRACING_DETAILS: Optional[dict] = None -if TRACING_ENABLED and not isRunningBackup(): # pragma: no cover - from InvenTree.tracing import setup_instruments, setup_tracing - - _t_endpoint = get_setting('INVENTREE_TRACING_ENDPOINT', 'tracing.endpoint', None) - _t_headers = get_setting('INVENTREE_TRACING_HEADERS', 'tracing.headers', None, dict) - - if _t_headers is None: - _t_headers = {} - - if _t_endpoint: - logger.info('OpenTelemetry tracing enabled') - - TRACING_DETAILS = ( - TRACING_DETAILS - if TRACING_DETAILS - else { - 'endpoint': _t_endpoint, - 'headers': _t_headers, - 'resources_input': { - **{'inventree.env.' + k: v for k, v in inventree_tags.items()}, - **get_setting( - 'INVENTREE_TRACING_RESOURCES', - 'tracing.resources', - default_value=None, - typecast=dict, - ), - }, - 'console': get_boolean_setting( - 'INVENTREE_TRACING_CONSOLE', 'tracing.console', False - ), - 'auth': get_setting( - 'INVENTREE_TRACING_AUTH', - 'tracing.auth', - default_value=None, - typecast=dict, - ), - 'is_http': get_setting( - 'INVENTREE_TRACING_IS_HTTP', 'tracing.is_http', True - ), - 'append_http': get_boolean_setting( - 'INVENTREE_TRACING_APPEND_HTTP', 'tracing.append_http', True - ), - } - ) - - # Run tracing/logging instrumentation - setup_tracing(**TRACING_DETAILS) - setup_instruments(DB_ENGINE) - else: - logger.warning('OpenTelemetry tracing not enabled because endpoint is not set') - -# endregion +TRACING_DETAILS: Optional[dict] = tracing.configure_tracing( + DB_ENGINE, TRACING_ENABLED, inventree_tags +) # Cache configuration GLOBAL_CACHE_ENABLED = is_global_cache_enabled() CACHES = {'default': get_cache_config(GLOBAL_CACHE_ENABLED)} -_q_worker_timeout = int( - get_setting('INVENTREE_BACKGROUND_TIMEOUT', 'background.timeout', 90) +# Background task processing with django-q +Q_CLUSTER = worker.get_worker_config( + DB_ENGINE, + global_cache=GLOBAL_CACHE_ENABLED, + sentry_dsn=SENTRY_DSN if SENTRY_ENABLED and SENTRY_DSN else None, + debug=DEBUG, ) - -# Prevent running multiple background workers if global cache is disabled -# This is to prevent scheduling conflicts due to the lack of a shared cache -BACKGROUND_WORKER_COUNT = ( - int(get_setting('INVENTREE_BACKGROUND_WORKERS', 'background.workers', 4)) - if GLOBAL_CACHE_ENABLED - else 1 -) - -# django-q background worker configuration -Q_CLUSTER = { - 'name': 'InvenTree', - 'label': 'Background Tasks', - 'workers': BACKGROUND_WORKER_COUNT, - 'timeout': _q_worker_timeout, - 'retry': max(120, _q_worker_timeout + 30), - 'max_attempts': int( - get_setting('INVENTREE_BACKGROUND_MAX_ATTEMPTS', 'background.max_attempts', 5) - ), - 'queue_limit': 50, - 'catch_up': False, - 'bulk': 10, - 'orm': 'default', - 'cache': 'default', - 'sync': False, - 'poll': 1.5, -} - -# Configure django-q sentry integration -if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover - Q_CLUSTER['error_reporter'] = {'sentry': {'dsn': SENTRY_DSN}} - -if GLOBAL_CACHE_ENABLED: # pragma: no cover - # If using external redis cache, make the cache the broker for Django Q - # as well - Q_CLUSTER['django_redis'] = 'worker' - - SILENCED_SYSTEM_CHECKS = ['templates.E003', 'templates.W003'] # Password validation @@ -1045,10 +686,10 @@ INTERNAL_EMAIL_BACKEND = get_setting( ) # SMTP backend -EMAIL_HOST = get_setting('INVENTREE_EMAIL_HOST', 'email.host', '') +EMAIL_HOST = get_setting('INVENTREE_EMAIL_HOST', 'email.host') EMAIL_PORT = get_setting('INVENTREE_EMAIL_PORT', 'email.port', 25, typecast=int) -EMAIL_HOST_USER = get_setting('INVENTREE_EMAIL_USERNAME', 'email.username', '') -EMAIL_HOST_PASSWORD = get_setting('INVENTREE_EMAIL_PASSWORD', 'email.password', '') +EMAIL_HOST_USER = get_setting('INVENTREE_EMAIL_USERNAME', 'email.username') +EMAIL_HOST_PASSWORD = get_setting('INVENTREE_EMAIL_PASSWORD', 'email.password') EMAIL_USE_TLS = get_boolean_setting('INVENTREE_EMAIL_TLS', 'email.tls', False) EMAIL_USE_SSL = get_boolean_setting('INVENTREE_EMAIL_SSL', 'email.ssl', False) # Anymail @@ -1219,16 +860,14 @@ LANGUAGE_COOKIE_SAMESITE = COOKIE_MODE - Otherwise, use the value specified in the configuration file (or env var) """ COOKIE_SECURE = ( - False - if DEBUG - else ( - SESSION_COOKIE_SAMESITE == 'None' - or get_boolean_setting( - 'INVENTREE_SESSION_COOKIE_SECURE', 'cookie.secure', False - ) - ) + get_boolean_setting('INVENTREE_SESSION_COOKIE_SECURE', 'cookie.secure', False) + or SESSION_COOKIE_SAMESITE == 'None' ) +# Override COOKIE_SECURE value in DEBUG mode +if DEBUG: + COOKIE_SECURE = False + CSRF_COOKIE_SECURE = COOKIE_SECURE SESSION_COOKIE_SECURE = COOKIE_SECURE LANGUAGE_COOKIE_SECURE = COOKIE_SECURE diff --git a/src/backend/InvenTree/InvenTree/sso.py b/src/backend/InvenTree/InvenTree/sso.py index 05bacaf38d..d04abf21ba 100644 --- a/src/backend/InvenTree/InvenTree/sso.py +++ b/src/backend/InvenTree/InvenTree/sso.py @@ -49,7 +49,7 @@ def check_provider(provider): if not app: return False - if allauth.app_settings.SITES_ENABLED: # type: ignore[unresolved-attribute] + if allauth.app_settings.SITES_ENABLED: # At least one matching site must be specified if not app.sites.exists(): logger.error('SocialApp %s has no sites configured', app) diff --git a/src/backend/InvenTree/InvenTree/tasks.py b/src/backend/InvenTree/InvenTree/tasks.py index 887c11899d..c231bf2197 100644 --- a/src/backend/InvenTree/InvenTree/tasks.py +++ b/src/backend/InvenTree/InvenTree/tasks.py @@ -29,7 +29,6 @@ from maintenance_mode.core import ( from opentelemetry import trace from common.settings import get_global_setting, set_global_setting -from InvenTree.config import get_setting from plugin import registry from .version import isInvenTreeUpToDate @@ -159,15 +158,71 @@ def record_task_success(task_name: str): set_global_setting(f'_{task_name}_SUCCESS', datetime.now().isoformat(), None) +def check_existing_task(taskname, group: str, *args, **kwargs) -> Optional[str]: + """Test if an identical task is already registered with the worker. + + This will only return true if the task name, group, args and kwargs all match an existing task. + + Arguments: + taskname: The name of the task to check for, in the format 'app.module.function' + group: The group that the task belongs to + *args: Positional arguments to match + **kwargs: Keyword arguments to match + + Returns: + Optional[str]: The ID of the matching task, if found, otherwise None + """ + from django_q.models import OrmQ + + task_id = None + + # Iterate through all available tasks, with the most recent first + for task in OrmQ.objects.all().order_by('-id'): + if task.func() != taskname and task.task.get('func') != taskname: + # Task does not match + continue + + if task.group() != group: + # Group does not match + continue + + if task.args() != args: + # Task args do not match + continue + + if task.kwargs() != kwargs: + # Task kwargs do not match + continue + + task_id = task.task_id() + + break + + return task_id + + def offload_task( - taskname, *args, force_async=False, force_sync=False, **kwargs -) -> bool: + taskname, + *args, + force_async: bool = False, + force_sync: bool = False, + check_duplicates: bool = True, + **kwargs, +) -> str | bool: """Create an AsyncTask if workers are running. This is different to a 'scheduled' task, in that it only runs once! If workers are not running or force_sync flag, is set then the task is ran synchronously. + Arguments: + taskname: The name of the task to be run, in the format 'app.module.function' + *args: Positional arguments to be passed to the task function + force_async: If True, force the task to be offloaded (even if workers are not running) + force_sync: If True, force the task to be run synchronously (even if workers are running) + check_duplicates: If True, check for existing identical tasks before offloading + **kwargs: Keyword arguments to be passed to the task function + Returns: - bool: True if the task was offloaded (or ran), False otherwise + str | bool: Task ID if the task was offloaded, True if ran synchronously, False otherwise """ from InvenTree.exceptions import log_error @@ -198,11 +253,23 @@ def offload_task( force_sync = True if force_async or (is_worker_running() and not force_sync): + # Before offloading, check if a duplicate task exists + if not force_sync and check_duplicates: + if task_id := check_existing_task(taskname, group, *args, **kwargs): + logger.debug( + "Skipping duplicate task '%s' with ID '%s'", taskname, task_id + ) + + return task_id + # Running as asynchronous task try: task = AsyncTask(taskname, *args, group=group, **kwargs) with tracer.start_as_current_span(f'async worker: {taskname}'): task.run() + + # Return the ID of the offloaded task, so that it can be tracked if needed + return task.id except ImportError: raise_warning(f"WARNING: '{taskname}' not offloaded - Function not found") return False @@ -265,6 +332,40 @@ def offload_task( return True +def get_queued_task(task_id: str): + """Find the task in the queue, if it exists. + + Note that the OrmQ table does NOT keep the task ID as a database field, + it is instead stored in the payload data. + If there are a large number of pending tasks, this query may be inefficient, + but there is no other way to find a queued task by ID. + """ + offset = 0 + limit = 500 + + if not task_id: + # Return early if no task ID was provided + return None + + task_id = str(task_id) + + from django_q.models import OrmQ + + while True: + queued_tasks = OrmQ.objects.all().order_by('id')[offset : offset + limit] + if not queued_tasks: + break + + for task in queued_tasks: + if task.task_id() == task_id: + return task + + offset += limit + + # No matching task was discovered + return None + + @dataclass() class ScheduledTask: """A scheduled task. @@ -286,7 +387,7 @@ class ScheduledTask: QUARTERLY: str = 'Q' YEARLY: str = 'Y' - TYPE: tuple[str] = (MINUTES, HOURLY, DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY) # type: ignore[invalid-assignment] + TYPE: tuple[str] = (MINUTES, HOURLY, DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY) class TaskRegister: @@ -322,12 +423,12 @@ def scheduled_task( minutes (int, optional): The number of minutes between task runs. Defaults to None. tasklist (TaskRegister, optional): The list the tasks should be registered to. Defaults to None. + Returns: + _type_: _description_ + Raises: ValueError: If decorated object is not callable ValueError: If interval is not valid - - Returns: - _type_: _description_ """ def _task_wrapper(admin_class): @@ -720,7 +821,7 @@ def check_for_migrations(force: bool = False, reload_registry: bool = True) -> b set_pending_migrations(n) # Test if auto-updates are enabled - if not force and not get_setting('INVENTREE_AUTO_UPDATE', 'auto_update'): + if not force and not settings.AUTO_UPDATE: logger.info('Auto-update is disabled - skipping migrations') return False diff --git a/src/backend/InvenTree/InvenTree/test_api.py b/src/backend/InvenTree/InvenTree/test_api.py index 7aeacb6751..5475edd03a 100644 --- a/src/backend/InvenTree/InvenTree/test_api.py +++ b/src/backend/InvenTree/InvenTree/test_api.py @@ -278,8 +278,7 @@ class BulkDeleteTests(InvenTreeAPITestCase): response = self.delete(url, {}, expected_code=400) self.assertIn( - 'List of items or filters must be provided for bulk operation', - str(response.data), + 'List of items must be provided for bulk operation', str(response.data) ) # DELETE with invalid 'items' @@ -287,11 +286,6 @@ class BulkDeleteTests(InvenTreeAPITestCase): self.assertIn('Items must be provided as a list', str(response.data)) - # DELETE with invalid 'filters' - response = self.delete(url, {'filters': [1, 2, 3]}, expected_code=400) - - self.assertIn('Filters must be provided as a dict', str(response.data)) - class SearchTests(InvenTreeAPITestCase): """Unit tests for global search endpoint.""" @@ -574,7 +568,7 @@ class GeneralApiTests(InvenTreeAPITestCase): self.assertIn('License file not found at', str(log.output)) - with TemporaryDirectory() as tmp: # type: ignore[no-matching-overload] + with TemporaryDirectory() as tmp: sample_file = Path(tmp, 'temp.txt') sample_file.write_text('abc', 'utf-8') diff --git a/src/backend/InvenTree/InvenTree/test_serializers.py b/src/backend/InvenTree/InvenTree/test_serializers.py index b6c794e33f..aeccf73d4b 100644 --- a/src/backend/InvenTree/InvenTree/test_serializers.py +++ b/src/backend/InvenTree/InvenTree/test_serializers.py @@ -8,6 +8,7 @@ from rest_framework.serializers import SerializerMethodField import InvenTree.serializers from InvenTree.mixins import ListCreateAPI, OutputOptionsMixin +from InvenTree.serializers import OptionalField from InvenTree.unit_test import InvenTreeAPITestCase from InvenTree.urls import backendpatterns @@ -25,21 +26,25 @@ class SampleSerializer( fields = ['field_a', 'field_b', 'field_c', 'field_d', 'field_e', 'id'] field_a = SerializerMethodField(method_name='sample') - field_b = InvenTree.serializers.enable_filter( - InvenTree.serializers.FilterableSerializerMethodField(method_name='sample') + field_b = OptionalField( + serializer_class=SerializerMethodField, + serializer_kwargs={'method_name': 'sample'}, ) - field_c = InvenTree.serializers.enable_filter( - InvenTree.serializers.FilterableSerializerMethodField(method_name='sample'), - True, + field_c = OptionalField( + serializer_class=SerializerMethodField, + serializer_kwargs={'method_name': 'sample'}, + default_include=True, filter_name='crazy_name', ) - field_d = InvenTree.serializers.enable_filter( - InvenTree.serializers.FilterableSerializerMethodField(method_name='sample'), - True, + field_d = OptionalField( + serializer_class=SerializerMethodField, + serializer_kwargs={'method_name': 'sample'}, + default_include=True, filter_name='crazy_name', ) - field_e = InvenTree.serializers.enable_filter( - InvenTree.serializers.FilterableSerializerMethodField(method_name='sample'), + field_e = OptionalField( + serializer_class=SerializerMethodField, + serializer_kwargs={'method_name': 'sample'}, filter_name='field_e', filter_by_query=False, ) @@ -106,110 +111,3 @@ class FilteredSerializers(InvenTreeAPITestCase): self.assertContains(response, 'field_c') self.assertContains(response, 'field_d') self.assertNotContains(response, 'field_e') - - def test_failiure_enable_filter(self): - """Test sanity check for enable_filter.""" - # Allowed usage - field_b = InvenTree.serializers.enable_filter( # noqa: F841 - InvenTree.serializers.FilterableSerializerMethodField(method_name='sample') - ) - - # Disallowed usage - with self.assertRaises(Exception) as cm: - field_a = InvenTree.serializers.enable_filter( # noqa: F841 - SerializerMethodField(method_name='sample') - ) - self.assertIn( - 'INVE-I2: `enable_filter` can only be applied to serializer fields', - str(cm.exception), - ) - - def test_failiure_FilterableSerializerMixin(self): - """Test failure case for FilteredSerializerMixin.""" - - class BadSerializer( - InvenTree.serializers.FilterableSerializerMixin, - InvenTree.serializers.InvenTreeModelSerializer, - ): - """Bad serializer for testing FilterableSerializerMixin.""" - - class Meta: - """Meta options.""" - - model = User - fields = ['field_a', 'id'] - - field_a = SerializerMethodField(method_name='sample') - - def sample(self, obj): - """Sample method field.""" - return 'sample' # pragma: no cover - - with self.assertRaises(Exception) as cm: - _ = BadSerializer() - self.assertIn( - 'INVE-I2: No filter targets found in fields, remove `PathScopedMixin`', - str(cm.exception), - ) - - # Test override - BadSerializer.no_filters = True - _ = BadSerializer() - self.assertTrue(True) # Dummy assertion to ensure we reach here - - def test_failure_OutputOptionsMixin(self): - """Test failure case for OutputOptionsMixin.""" - - class BadSerializer(InvenTree.serializers.InvenTreeModelSerializer): - """Sample serializer.""" - - class Meta: - """Meta options.""" - - model = User - fields = ['id'] - - field_a = SerializerMethodField(method_name='sample') - - # Bad implementation of OutputOptionsMixin - with self.assertRaises(Exception) as cm: - - class BadList(OutputOptionsMixin, ListCreateAPI): - """Bad list endpoint for testing OutputOptionsMixin.""" - - serializer_class = BadSerializer - queryset = User.objects.all() - permission_classes = [] - - self.assertTrue(True) - _ = BadList() # this should raise an exception - self.assertEqual( - str(cm.exception), - 'INVE-I2: `OutputOptionsMixin` can only be used with serializers that contain the `FilterableSerializerMixin` mixin', - ) - - # More creative bad implementation - with self.assertRaises(Exception) as cm: - - class BadList(OutputOptionsMixin, ListCreateAPI): - """Bad list endpoint for testing OutputOptionsMixin.""" - - queryset = User.objects.all() - permission_classes = [] - - def get_serializer(self, *args, **kwargs): - """Get serializer override.""" - self.serializer_class = BadSerializer - return super().get_serializer(*args, **kwargs) - - view = BadList() - self.assertTrue(True) - # mock some stuff to allow get_serializer to run - view.request = self.client.request() - view.format_kwarg = {} - view.get_serializer() # this should raise an exception - - self.assertEqual( - str(cm.exception), - 'INVE-I2: `OutputOptionsMixin` can only be used with serializers that contain the `FilterableSerializerMixin` mixin', - ) diff --git a/src/backend/InvenTree/InvenTree/test_tasks.py b/src/backend/InvenTree/InvenTree/test_tasks.py index f169292711..04df009198 100644 --- a/src/backend/InvenTree/InvenTree/test_tasks.py +++ b/src/backend/InvenTree/InvenTree/test_tasks.py @@ -10,7 +10,7 @@ from django.db.utils import NotSupportedError from django.test import TestCase from django.utils import timezone -from django_q.models import Schedule, Task +from django_q.models import OrmQ, Schedule, Task from error_report.models import Error import InvenTree.tasks @@ -234,11 +234,8 @@ class InvenTreeTaskTests(PluginRegistryMixin, TestCase): msg = NotificationMessage.objects.last() - self.assertEqual(msg.name, 'Task Failure') - self.assertEqual( - msg.message, - "Background worker task 'InvenTree.tasks.failed_task' failed after 10 attempts", - ) + self.assertEqual(msg.name, 'Server Error') + self.assertEqual(msg.message, 'An error has been logged by the server.') def test_delete_old_emails(self): """Test the delete_old_emails task.""" @@ -297,3 +294,74 @@ class InvenTreeTaskTests(PluginRegistryMixin, TestCase): ) msg.timestamp = timestamp msg.save() + + def test_duplicate_tasks(self): + """Test for task duplication.""" + # Start with a blank slate + OrmQ.objects.all().delete() + + # Add some unique tasks + for idx in range(10): + InvenTree.tasks.offload_task( + f'dummy_module.dummy_function_{idx}', force_async=True + ) + + self.assertEqual(OrmQ.objects.count(), 10) + + # Add some duplicate tasks + for _idx in range(10): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function_x', + 1, + 2, + 3, + animal='cat', + vegetable='carrot', + force_async=True, + ) + + # Only 1 extra task should have been added + self.assertEqual(OrmQ.objects.count(), 11) + + # Add some more duplicate tasks, but ignore duplication checks + for _idx in range(10): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function_y', + 1, + 2, + 3, + animal='dog', + vegetable='yam', + force_async=True, + check_duplicates=False, + ) + + # 10 extra tasks should have been added + self.assertEqual(OrmQ.objects.count(), 21) + + # Add more tasks, which are *not* duplicates based on args + for idx in range(10): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', + 1, + idx, + 3, + animal='cat', + vegetable='carrot', + force_async=True, + ) + + # Add more tasks, which are *not* duplicates based on kwargs + for idx in range(10): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', + 1, + 2, + 3, + animal='cat', + vegetable=f'vegetable_{idx}', + force_async=True, + ) + + # 20 more tasks should have been added + self.assertEqual(OrmQ.objects.count(), 41) diff --git a/src/backend/InvenTree/InvenTree/tests.py b/src/backend/InvenTree/InvenTree/tests.py index 37497465c2..d00c868133 100644 --- a/src/backend/InvenTree/InvenTree/tests.py +++ b/src/backend/InvenTree/InvenTree/tests.py @@ -691,23 +691,26 @@ class TestHelpers(TestCase): self.assertFalse(helpers.isNull(s)) def testStaticUrl(self): - """Test static url helpers.""" + """Test static URL helpers.""" self.assertEqual(helpers.getStaticUrl('test.jpg'), '/static/test.jpg') self.assertEqual(helpers.getBlankImage(), '/static/img/blank_image.png') self.assertEqual( helpers.getBlankThumbnail(), '/static/img/blank_image.thumbnail.png' ) + self.assertFalse(helpers.checkStaticFile('dummy', 'dir', 'test.jpg')) + self.assertTrue(helpers.checkStaticFile('img', 'blank_image.png')) + def testMediaUrl(self): """Test getMediaUrl.""" # Str should not work with self.assertRaises(TypeError): - helpers.getMediaUrl('xx/yy.png') # type: ignore + helpers.getMediaUrl('xx/yy.png') # Correct usage part = Part().image self.assertEqual( - helpers.getMediaUrl(StdImageFieldFile(part, part, 'xx/yy.png')), # type: ignore + helpers.getMediaUrl(StdImageFieldFile(part, part, 'xx/yy.png')), # ty:ignore[too-many-positional-arguments] '/media/xx/yy.png', ) @@ -734,21 +737,10 @@ class TestHelpers(TestCase): large_img = 'https://github.com/inventree/InvenTree/raw/master/src/backend/InvenTree/InvenTree/static/img/paper_splash_large.jpg' - InvenTreeSetting.set_setting( - 'INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE', 1, change_user=None - ) - - # Attempt to download an image which is too large - with self.assertRaises(ValueError): - InvenTree.helpers_model.download_image_from_url(large_img, timeout=10) - - # Increase allowable download size - InvenTreeSetting.set_setting( - 'INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE', 5, change_user=None - ) - # Download a valid image (should not throw an error) - InvenTree.helpers_model.download_image_from_url(large_img, timeout=10) + InvenTree.helpers_model.download_image_from_url( + large_img, timeout=10, max_size=10 * 1024 * 1024 + ) def test_model_mixin(self): """Test the getModelsWithMixin function.""" @@ -1550,11 +1542,11 @@ class SanitizerTest(TestCase): def test_svg_sanitizer(self): """Test that SVGs are sanitized accordingly.""" valid_string = """{0} - + """ dangerous_string = valid_string.format('') - # Test that valid string + # Test that valid string passes through unchanged self.assertEqual(valid_string, sanitize_svg(valid_string)) # Test that invalid string is cleaned diff --git a/src/backend/InvenTree/InvenTree/tracing.py b/src/backend/InvenTree/InvenTree/tracing.py index 4cedbb584d..f97da6c0eb 100644 --- a/src/backend/InvenTree/InvenTree/tracing.py +++ b/src/backend/InvenTree/InvenTree/tracing.py @@ -4,7 +4,7 @@ import base64 import logging from typing import Optional -from opentelemetry import metrics, trace # type: ignore[import] +from opentelemetry import metrics, trace from opentelemetry.instrumentation.django import DjangoInstrumentor from opentelemetry.instrumentation.redis import RedisInstrumentor from opentelemetry.instrumentation.requests import RequestsInstrumentor diff --git a/src/backend/InvenTree/InvenTree/urls.py b/src/backend/InvenTree/InvenTree/urls.py index 89c49ca89b..4b57455f73 100644 --- a/src/backend/InvenTree/InvenTree/urls.py +++ b/src/backend/InvenTree/InvenTree/urls.py @@ -20,6 +20,7 @@ import build.api import common.api import company.api import importer.api +import InvenTree.logging # noqa: F401 - ensure logging handlers are registered import machine.api import order.api import part.api diff --git a/src/backend/InvenTree/InvenTree/version.py b/src/backend/InvenTree/InvenTree/version.py index b66f834e06..b2b211b791 100644 --- a/src/backend/InvenTree/InvenTree/version.py +++ b/src/backend/InvenTree/InvenTree/version.py @@ -12,12 +12,10 @@ import sys from datetime import datetime as dt from datetime import timedelta as td -from django.conf import settings - from .api_version import INVENTREE_API_TEXT, INVENTREE_API_VERSION # InvenTree software version -INVENTREE_SW_VERSION = '1.3.0 dev' +INVENTREE_SW_VERSION = '1.4.0 dev' # Minimum supported Python version MIN_PYTHON_VERSION = (3, 11) @@ -39,6 +37,8 @@ try: output = logger.warning try: + from django.conf import settings + if settings.DOCKER: output = logger.info except Exception: @@ -289,8 +289,10 @@ def inventreeBranch(): return ' '.join(branch.splitlines()) if main_branch is None: - return None - return main_branch.decode('utf-8') + return None # pragma: no cover - branch information may not be available in all environments + return main_branch.decode( + 'utf-8' + ) # pragma: no cover - branch information may not be available in all environments def inventreeTarget(): diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py index a5c601e164..8a7771c2db 100644 --- a/src/backend/InvenTree/build/api.py +++ b/src/backend/InvenTree/build/api.py @@ -11,12 +11,13 @@ import django_filters.rest_framework.filters as rest_filters from django_filters.rest_framework.filterset import FilterSet from drf_spectacular.utils import extend_schema, extend_schema_field from rest_framework import serializers, status -from rest_framework.exceptions import ValidationError +from rest_framework.exceptions import NotFound, ValidationError from rest_framework.response import Response import build.models as build_models import build.serializers import common.models +import common.serializers import part.models as part_models import stock.models as stock_models import stock.serializers @@ -27,7 +28,7 @@ from generic.states.api import StatusView from InvenTree.api import BulkDeleteMixin, ParameterListMixin from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( - SEARCH_ORDER_FILTER_ALIAS, + SEARCH_ORDER_FILTER, InvenTreeDateFilter, NumberOrNullFilter, ) @@ -145,8 +146,8 @@ class BuildFilter(FilterSet): def filter_overdue(self, queryset, name, value): """Filter the queryset to either include or exclude orders which are overdue.""" if str2bool(value): - return queryset.filter(Build.OVERDUE_FILTER) - return queryset.exclude(Build.OVERDUE_FILTER) + return queryset.filter(Build.get_overdue_filter()) + return queryset.exclude(Build.get_overdue_filter()) assigned_to_me = rest_filters.BooleanFilter( label=_('Assigned to me'), method='filter_assigned_to_me' @@ -343,7 +344,7 @@ class BuildList( output_options = BuildListOutputOptions filterset_class = BuildFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_fields = [ 'reference', 'part', @@ -385,6 +386,20 @@ class BuildList( kwargs['create'] = True return super().get_serializer(*args, **kwargs) + def create(self, request, *args, **kwargs): + """Save user information on order creation.""" + 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() + + headers = self.get_success_headers(serializer.data) + return Response( + serializer.data, status=status.HTTP_201_CREATED, headers=headers + ) + class BuildDetail(BuildMixin, RetrieveUpdateDestroyAPI): """API endpoint for detail view of a Build object.""" @@ -594,7 +609,7 @@ class BuildLineList( """API endpoint for accessing a list of BuildLine objects.""" filterset_class = BuildLineFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = BuildLineOutputOptions ordering_fields = [ 'part', @@ -662,6 +677,13 @@ class BuildLineDetail(BuildLineMixin, OutputOptionsMixin, RetrieveUpdateDestroyA class BuildOrderContextMixin: """Mixin class which adds build order as serializer context variable.""" + def get_build(self): + """Return the Build object associated with this API endpoint.""" + try: + return Build.objects.get(pk=self.kwargs.get('pk', None)) + except (ValueError, Build.DoesNotExist): + raise NotFound(_('Build not found')) + def get_serializer_context(self): """Add extra context information to the endpoint serializer.""" ctx = super().get_serializer_context() @@ -670,8 +692,8 @@ class BuildOrderContextMixin: ctx['to_complete'] = True try: - ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None)) - except Exception: + ctx['build'] = self.get_build() + except NotFound: pass return ctx @@ -713,14 +735,81 @@ class BuildOutputScrap(BuildOrderContextMixin, CreateAPI): ctx['to_complete'] = False return ctx + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Override POST to offload scrapping to the background worker.""" + from build.tasks import scrap_build_outputs + from InvenTree.tasks import offload_task + + build = self.get_build() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + task_id = offload_task( + scrap_build_outputs, + build.pk, + outputs=[ + { + 'output_id': item['output'].pk, + 'quantity': float(item['quantity']) + if item.get('quantity') is not None + else None, + } + for item in data['outputs'] + ], + location_id=data['location'].pk, + notes=data.get('notes', ''), + discard_allocations=data.get('discard_allocations', False), + user_id=self.request.user.pk, + group='build', + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class BuildOutputComplete(BuildOrderContextMixin, CreateAPI): """API endpoint for completing build outputs.""" queryset = Build.objects.none() - serializer_class = build.serializers.BuildOutputCompleteSerializer + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Override POST to offload build output completion to the background worker.""" + from build.tasks import complete_build_outputs + from InvenTree.tasks import offload_task + + build = self.get_build() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + location = data.get('location') + + task_id = offload_task( + complete_build_outputs, + build.pk, + outputs=[ + { + 'output_id': item['output'].pk, + 'quantity': float(item['quantity']) + if item.get('quantity') is not None + else None, + } + for item in data['outputs'] + ], + location_id=location.pk if location else None, + status=data.get('status_custom_key'), + notes=data.get('notes', ''), + user_id=self.request.user.pk, + group='build', + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class BuildOutputDelete(BuildOrderContextMixin, CreateAPI): """API endpoint for deleting multiple build outputs.""" @@ -728,15 +817,33 @@ class BuildOutputDelete(BuildOrderContextMixin, CreateAPI): def get_serializer_context(self): """Add extra context information to the endpoint serializer.""" ctx = super().get_serializer_context() - ctx['to_complete'] = False - return ctx queryset = Build.objects.none() - serializer_class = build.serializers.BuildOutputDeleteSerializer + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Override POST to offload build output deletion to the background worker.""" + from build.tasks import delete_build_outputs + from InvenTree.tasks import offload_task + + build = self.get_build() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + task_id = offload_task( + delete_build_outputs, + build.pk, + output_ids=[item['output'].pk for item in data['outputs']], + group='build', + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class BuildFinish(BuildOrderContextMixin, CreateAPI): """API endpoint for marking a build as finished (completed).""" @@ -764,6 +871,37 @@ class BuildAutoAllocate(BuildOrderContextMixin, CreateAPI): queryset = Build.objects.none() serializer_class = build.serializers.BuildAutoAllocationSerializer + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Override the POST method to handle auto allocation task. + + As this is offloaded to the background task, + we return information about the background task which is performing the auto allocation operation. + """ + from build.tasks import auto_allocate_build + from InvenTree.tasks import offload_task + + build = self.get_build() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + # Offload the task to the background worker + task_id = offload_task( + auto_allocate_build, + build.pk, + location=data.get('location', None), + exclude_location=data.get('exclude_location', None), + interchangeable=data['interchangeable'], + substitutes=data['substitutes'], + optional_items=data['optional_items'], + item_type=data.get('item_type', 'untracked'), + group='build', + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class BuildAllocate(BuildOrderContextMixin, CreateAPI): """API endpoint to allocate stock items to a build order. @@ -786,6 +924,39 @@ class BuildConsume(BuildOrderContextMixin, CreateAPI): queryset = Build.objects.none() serializer_class = build.serializers.BuildConsumeSerializer + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Override the POST method to handle consume task. + + As this is offloaded to the background task, + we return information about the background task which is performing the consume operation. + """ + from build.tasks import consume_build_stock + from InvenTree.tasks import offload_task + + build = self.get_build() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + # Extract the information we need to consume build stock + items = data.get('items', []) + lines = data.get('lines', []) + notes = data.get('notes', '') + + # Offload the task to the background worker + task_id = offload_task( + consume_build_stock, + build.pk, + lines=[line['build_line'].pk for line in lines], + items={item['build_item'].pk: item['quantity'] for item in items}, + user_id=self.request.user.pk, + notes=notes, + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class BuildIssue(BuildOrderContextMixin, CreateAPI): """API endpoint for issuing a BuildOrder.""" @@ -951,7 +1122,7 @@ class BuildItemList( output_options = BuildItemOutputOptions filterset_class = BuildItemFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER def get_queryset(self): """Override the queryset method, to perform custom prefetch.""" diff --git a/src/backend/InvenTree/build/models.py b/src/backend/InvenTree/build/models.py index 1662088163..c3691c5677 100644 --- a/src/backend/InvenTree/build/models.py +++ b/src/backend/InvenTree/build/models.py @@ -1,7 +1,7 @@ """Build database model definitions.""" import decimal -from typing import Optional +from typing import Optional, TypedDict from django.contrib.auth.models import User from django.core.exceptions import ValidationError @@ -37,7 +37,6 @@ from build.validators import ( validate_build_order_reference, ) from common.models import ProjectCode -from common.notifications import InvenTreeNotificationBodies, trigger_notification from common.settings import ( get_global_setting, prevent_build_output_complete_on_incompleted_tests, @@ -50,7 +49,7 @@ from stock.status_codes import StockHistoryCode, StockStatus logger = structlog.get_logger('inventree') -class BuildReportContext(report.mixins.BaseReportContext): +class BuildReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the Build model. Attributes: @@ -132,11 +131,14 @@ class Build( TRACKED = 'tracked' # Tracked BOM items UNTRACKED = 'untracked' # Untracked BOM items - OVERDUE_FILTER = ( - Q(status__in=BuildStatusGroups.ACTIVE_CODES) - & ~Q(target_date=None) - & Q(target_date__lte=InvenTree.helpers.current_date()) - ) + @classmethod + def get_overdue_filter(cls): + """Filter for determining if a build order is overdue.""" + return ( + Q(status__in=BuildStatusGroups.ACTIVE_CODES) + & ~Q(target_date=None) + & Q(target_date__lte=InvenTree.helpers.current_date()) + ) # Global setting for specifying reference pattern REFERENCE_PATTERN_SETTING = 'BUILDORDER_REFERENCE_PATTERN' @@ -400,6 +402,14 @@ class Build( related_name='builds_issued', ) + @property + def created_by(self): + """Alias for issued_by field. + + This is used for compatibility with the order models + """ + return self.issued_by + responsible = models.ForeignKey( users.models.Owner, on_delete=models.SET_NULL, @@ -465,7 +475,7 @@ class Build( bool: Is the build overdue """ query = Build.objects.filter(pk=self.pk) - query = query.filter(Build.OVERDUE_FILTER) + query = query.filter(Build.get_overdue_filter()) return query.exists() @@ -640,7 +650,6 @@ class Build( return self.is_fully_allocated(tracked=False) - @transaction.atomic def complete_allocations(self, user) -> None: """Complete all stock allocations for this build order. @@ -651,7 +660,7 @@ class Build( # Ensure that there are no longer any BuildItem objects # which point to this Build Order - self.allocated_stock.delete() + self.allocated_stock.all().delete() @transaction.atomic def complete_build(self, user: User, trim_allocated_stock: bool = False): @@ -691,66 +700,20 @@ class Build( _('Cannot complete build order with incomplete outputs') ) - if trim_allocated_stock: - self.trim_allocated_stock() + # Offload background task to complete build allocations + InvenTree.tasks.offload_task( + build.tasks.complete_build, + self.pk, + user.pk if user else None, + trim_allocated_stock=trim_allocated_stock, + group='build', + ) self.completion_date = InvenTree.helpers.current_date() self.completed_by = user self.status = BuildStatus.COMPLETE.value self.save() - # Offload task to complete build allocations - if not InvenTree.tasks.offload_task( - build.tasks.complete_build_allocations, - self.pk, - user.pk if user else None, - group='build', - ): - raise ValidationError( - _('Failed to offload task to complete build allocations') - ) - - # Register an event - trigger_event(BuildEvents.COMPLETED, id=self.pk) - - # Notify users that this build has been completed - targets = [self.issued_by, self.responsible] - - # Also inform anyone subscribed to the assembly part - targets.extend(self.part.get_subscribers()) - - # Notify those users interested in the parent build - if self.parent: - targets.append(self.parent.issued_by) - targets.append(self.parent.responsible) - - # Notify users if this build points to a sales order - if self.sales_order: - targets.append(self.sales_order.created_by) - targets.append(self.sales_order.responsible) - - build = self - name = _(f'Build order {build} has been completed') - - context = { - 'build': build, - 'name': name, - 'slug': 'build.completed', - 'message': _('A build order has been completed'), - 'link': InvenTree.helpers_model.construct_absolute_url( - self.get_absolute_url() - ), - 'template': {'html': 'email/build_order_completed.html', 'subject': name}, - } - - trigger_notification( - build, - 'build.completed', - targets=targets, - context=context, - target_exclude=[user], - ) - @transaction.atomic def issue_build(self): """Mark the Build as IN PRODUCTION. @@ -828,26 +791,15 @@ class Build( remove_allocated_stock = kwargs.get('remove_allocated_stock', False) remove_incomplete_outputs = kwargs.get('remove_incomplete_outputs', False) - if remove_allocated_stock: - # Offload task to remove allocated stock - if not InvenTree.tasks.offload_task( - build.tasks.complete_build_allocations, - self.pk, - user.pk if user else None, - group='build', - ): - raise ValidationError( - _('Failed to offload task to complete build allocations') - ) - - else: - self.allocated_stock.all().delete() - - # Remove incomplete outputs (if required) - if remove_incomplete_outputs: - outputs = self.build_outputs.filter(is_building=True) - - outputs.delete() + # Offload background task to take care of the expensive operations + InvenTree.tasks.offload_task( + build.tasks.cancel_build, + self.pk, + user.pk if user else None, + remove_allocated_stock=remove_allocated_stock, + remove_incomplete_outputs=remove_incomplete_outputs, + group='build', + ) # Date of 'completion' is the date the build was cancelled self.completion_date = InvenTree.helpers.current_date() @@ -856,17 +808,6 @@ class Build( self.status = BuildStatus.CANCELLED.value self.save() - # Notify users that the order has been canceled - InvenTree.helpers_model.notify_responsible( - self, - Build, - exclude=self.issued_by, - content=InvenTreeNotificationBodies.OrderCanceled, - extra_users=self.part.get_subscribers(), - ) - - trigger_event(BuildEvents.CANCELLED, id=self.pk) - @transaction.atomic def deallocate_stock(self, build_line=None, output=None): """Deallocate stock from this Build. @@ -964,10 +905,10 @@ class Build( allocations.extend(new_allocations) # Bulk create tracking entries - stock.models.StockItemTracking.objects.bulk_create(tracking) + stock.models.StockItemTracking.objects.bulk_create(tracking, batch_size=250) # Generate stock allocations - BuildItem.objects.bulk_create(allocations) + BuildItem.objects.bulk_create(allocations, batch_size=250) else: """Create a single build output of the given quantity.""" @@ -1022,7 +963,9 @@ class Build( self.deallocate_stock(output=output) # Remove the build output from the database - output.delete() + # This is a special case where serialized stock can be deleted, + # independedent of the global setting which normally prevents deletion of serialized stock items + output.delete(ignore_serial_check=True) @transaction.atomic def trim_allocated_stock(self): @@ -1036,7 +979,7 @@ class Build( lines = lines.exclude(bom_item__consumable=True) lines = lines.annotate(allocated=annotate_allocated_quantity()) - for build_line in lines: # type: ignore[non-iterable] + for build_line in lines: reduce_by = build_line.allocated - build_line.quantity if reduce_by <= 0: @@ -1070,7 +1013,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) - @transaction.atomic def subtract_allocated_stock(self, user) -> None: """Removes the allocated untracked items from stock.""" # Find all BuildItem objects which point to this build @@ -1378,7 +1320,7 @@ class Build( new_items.extend(self.auto_allocate_tracked_output(output, **kwargs)) # Bulk-create the new BuildItem objects - BuildItem.objects.bulk_create(new_items) + BuildItem.objects.bulk_create(new_items, batch_size=250) def auto_allocate_untracked_stock(self, **kwargs): """Automatically allocate untracked stock items against this build order. @@ -1509,17 +1451,17 @@ class Build( unallocated_quantity -= quantity except (ValidationError, serializers.ValidationError) as exc: - # Catch model errors and re-throw as DRF errors + # Re-raise with a Django-compatible validation payload raise ValidationError( - exc.message, detail=serializers.as_serializer_error(exc) - ) + serializers.as_serializer_error(exc) + ) from exc 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) + BuildItem.objects.bulk_create(new_items, batch_size=250) def unallocated_lines(self, tracked: Optional[bool] = None) -> QuerySet: """Returns a list of BuildLine objects which have not been fully allocated.""" @@ -1644,7 +1586,7 @@ class Build( lines.append(BuildLine(build=self, bom_item=bom_item, quantity=quantity)) - BuildLine.objects.bulk_create(lines) + BuildLine.objects.bulk_create(lines, batch_size=250) if len(lines) > 0: logger.info('Created %s BuildLine objects for BuildOrder', len(lines)) @@ -1692,7 +1634,7 @@ def after_save_build(sender, instance: Build, created: bool, **kwargs): instance.update_build_line_items() -class BuildLineReportContext(report.mixins.BaseReportContext): +class BuildLineReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the BuildLine model. Attributes: @@ -1742,6 +1684,7 @@ class BuildLine(report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeMo """Return the API URL used to access this model.""" return reverse('api-build-line-list') + # type def report_context(self) -> BuildLineReportContext: """Generate custom report context for this BuildLine object.""" return { diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py index db4fd7560b..d7cc0e5729 100644 --- a/src/backend/InvenTree/build/serializers.py +++ b/src/backend/InvenTree/build/serializers.py @@ -21,7 +21,6 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.serializers import ValidationError -import build.tasks import common.filters import common.settings import company.serializers @@ -36,9 +35,8 @@ from InvenTree.serializers import ( InvenTreeDecimalField, InvenTreeModelSerializer, NotesFieldMixin, - enable_filter, + OptionalField, ) -from InvenTree.tasks import offload_task from stock.generators import generate_batch_code from stock.models import StockItem, StockLocation from stock.serializers import ( @@ -51,7 +49,6 @@ from users.serializers import OwnerSerializer, UserSerializer from .models import Build, BuildItem, BuildLine from .status_codes import BuildStatus -from .tasks import consume_build_item, consume_build_line class BuildSerializer( @@ -107,7 +104,8 @@ class BuildSerializer( read_only_fields = [ 'completed', 'creation_date', - 'completion_data', + 'issued_by', + 'completion_date', 'status', 'status_text', 'level', @@ -119,9 +117,10 @@ class BuildSerializer( status_text = serializers.CharField(source='get_status_display', read_only=True) - part_detail = enable_filter( - part_serializers.PartBriefSerializer(source='part', many=False, read_only=True), - True, + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={'source': 'part', 'many': False, 'read_only': True}, + default_include=True, prefetch_fields=['part', 'part__category', 'part__pricing_data'], ) @@ -135,16 +134,22 @@ class BuildSerializer( overdue = serializers.BooleanField(read_only=True, default=False) - issued_by_detail = enable_filter( - UserSerializer(source='issued_by', read_only=True), - True, + issued_by_detail = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={'source': 'issued_by', 'read_only': True}, + default_include=True, filter_name='user_detail', prefetch_fields=['issued_by'], ) - responsible_detail = enable_filter( - OwnerSerializer(source='responsible', read_only=True, allow_null=True), - True, + responsible_detail = OptionalField( + serializer_class=OwnerSerializer, + serializer_kwargs={ + 'source': 'responsible', + 'read_only': True, + 'allow_null': True, + }, + default_include=True, filter_name='user_detail', prefetch_fields=['responsible'], ) @@ -168,7 +173,8 @@ class BuildSerializer( queryset = queryset.annotate( overdue=Case( When( - Build.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()) + Build.get_overdue_filter(), + then=Value(True, output_field=BooleanField()), ), default=Value(False, output_field=BooleanField()), ) @@ -456,18 +462,6 @@ class BuildOutputDeleteSerializer(serializers.Serializer): return data - def save(self): - """'save' the serializer to delete the build outputs.""" - data = self.validated_data - outputs = data.get('outputs', []) - - build = self.context['build'] - - with transaction.atomic(): - for item in outputs: - output = item['output'] - build.delete_output(output) - class BuildOutputScrapSerializer(serializers.Serializer): """Scrapping one or more build outputs.""" @@ -512,27 +506,6 @@ class BuildOutputScrapSerializer(serializers.Serializer): return data - def save(self): - """Save the serializer to scrap the build outputs.""" - build = self.context['build'] - request = self.context.get('request') - data = self.validated_data - outputs = data.get('outputs', []) - - # Scrap the build outputs - with transaction.atomic(): - for item in outputs: - output = item['output'] - quantity = item.get('quantity', None) - build.scrap_build_output( - output, - quantity, - data.get('location', None), - user=request.user if request else None, - notes=data.get('notes', ''), - discard_allocations=data.get('discard_allocations', False), - ) - class BuildOutputCompleteSerializer(serializers.Serializer): """DRF serializer for completing one or more build outputs.""" @@ -604,42 +577,6 @@ class BuildOutputCompleteSerializer(serializers.Serializer): return data - def save(self): - """Save the serializer to complete the build outputs.""" - build = self.context['build'] - request = self.context.get('request') - - data = self.validated_data - - location = data.get('location', None) - status = data.get('status_custom_key', StockStatus.OK.value) - notes = data.get('notes', '') - - outputs = data.get('outputs', []) - - # Cache some calculated values which can be passed to each output - required_tests = outputs[0]['output'].part.getRequiredTests() - prevent_on_incomplete = ( - common.settings.prevent_build_output_complete_on_incompleted_tests() - ) - - # Mark the specified build outputs as "complete" - with transaction.atomic(): - for item in outputs: - output = item['output'] - quantity = item.get('quantity', None) - - build.complete_build_output( - output, - request.user if request else None, - quantity=quantity, - location=location, - status=status, - notes=notes, - required_tests=required_tests, - prevent_on_incomplete=prevent_on_incomplete, - ) - class BuildIssueSerializer(serializers.Serializer): """DRF serializer for issuing a build order.""" @@ -1128,27 +1065,6 @@ class BuildAutoAllocationSerializer(serializers.Serializer): help_text=_('Select item type to auto-allocate'), ) - def save(self): - """Perform the auto-allocation step.""" - import InvenTree.tasks - - data = self.validated_data - - build_order = self.context['build'] - - if not InvenTree.tasks.offload_task( - build.tasks.auto_allocate_build, - build_order.pk, - location=data.get('location', None), - exclude_location=data.get('exclude_location', None), - interchangeable=data['interchangeable'], - substitutes=data['substitutes'], - optional_items=data['optional_items'], - item_type=data.get('item_type', 'untracked'), - group='build', - ): - raise ValidationError(_('Failed to start auto-allocation task')) - class BuildItemSerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, InvenTreeModelSerializer @@ -1223,31 +1139,33 @@ class BuildItemSerializer( ) # Extra (optional) detail fields - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - label=_('Part'), - source='stock_item.part', - many=False, - read_only=True, - allow_null=True, - pricing=False, - ), - True, + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'label': _('Part'), + 'source': 'stock_item.part', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'pricing': False, + }, + default_include=True, prefetch_fields=['stock_item__part'], ) - stock_item_detail = enable_filter( - StockItemSerializer( - source='stock_item', - read_only=True, - allow_null=True, - label=_('Stock Item'), - part_detail=False, - location_detail=False, - supplier_part_detail=False, - path_detail=False, - ), - True, + stock_item_detail = OptionalField( + serializer_class=StockItemSerializer, + serializer_kwargs={ + 'source': 'stock_item', + 'read_only': True, + 'allow_null': True, + 'label': _('Stock Item'), + 'part_detail': False, + 'location_detail': False, + 'supplier_part_detail': False, + 'path_detail': False, + }, + default_include=True, filter_name='stock_detail', prefetch_fields=[ 'stock_item', @@ -1257,18 +1175,19 @@ class BuildItemSerializer( ], ) - install_into_detail = enable_filter( - StockItemSerializer( - source='install_into', - read_only=True, - allow_null=True, - label=_('Install Into'), - part_detail=False, - location_detail=False, - supplier_part_detail=False, - path_detail=False, - ), - False, + install_into_detail = OptionalField( + serializer_class=StockItemSerializer, + serializer_kwargs={ + 'source': 'install_into', + 'read_only': True, + 'allow_null': True, + 'label': _('Install Into'), + 'part_detail': False, + 'location_detail': False, + 'supplier_part_detail': False, + 'path_detail': False, + }, + default_include=False, prefetch_fields=['install_into', 'install_into__part'], ) @@ -1276,26 +1195,28 @@ class BuildItemSerializer( label=_('Location'), source='stock_item.location', many=False, read_only=True ) - location_detail = enable_filter( - LocationBriefSerializer( - label=_('Location'), - source='stock_item.location', - read_only=True, - allow_null=True, - ), - True, + location_detail = OptionalField( + serializer_class=LocationBriefSerializer, + serializer_kwargs={ + 'label': _('Location'), + 'source': 'stock_item.location', + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['stock_item__location'], ) - build_detail = enable_filter( - BuildSerializer( - label=_('Build'), - source='build_line.build', - many=False, - read_only=True, - allow_null=True, - ), - True, + build_detail = OptionalField( + serializer_class=BuildSerializer, + serializer_kwargs={ + 'label': _('Build'), + 'source': 'build_line.build', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=[ 'build_line__build', 'build_line__build__part', @@ -1306,16 +1227,17 @@ class BuildItemSerializer( ], ) - supplier_part_detail = enable_filter( - company.serializers.SupplierPartSerializer( - label=_('Supplier Part'), - source='stock_item.supplier_part', - many=False, - read_only=True, - allow_null=True, - brief=True, - ), - False, + supplier_part_detail = OptionalField( + serializer_class=company.serializers.SupplierPartSerializer, + serializer_kwargs={ + 'label': _('Supplier Part'), + 'source': 'stock_item.supplier_part', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'brief': True, + }, + default_include=False, prefetch_fields=[ 'stock_item__supplier_part', 'stock_item__supplier_part__supplier', @@ -1405,11 +1327,15 @@ class BuildLineSerializer( read_only=True, ) - allocations = enable_filter( - BuildItemSerializer( - many=True, read_only=True, allow_null=True, build_detail=False - ), - True, + allocations = OptionalField( + serializer_class=BuildItemSerializer, + serializer_kwargs={ + 'many': True, + 'read_only': True, + 'allow_null': True, + 'build_detail': False, + }, + default_include=True, prefetch_fields=[ 'allocations', 'allocations__stock_item', @@ -1450,73 +1376,79 @@ class BuildLineSerializer( bom_item = serializers.PrimaryKeyRelatedField(label=_('BOM Item'), read_only=True) # Foreign key fields - bom_item_detail = enable_filter( - part_serializers.BomItemSerializer( - label=_('BOM Item'), - source='bom_item', - many=False, - read_only=True, - allow_null=True, - pricing=False, - substitutes=False, - sub_part_detail=False, - part_detail=False, - can_build=False, - ), - False, + bom_item_detail = OptionalField( + serializer_class=part_serializers.BomItemSerializer, + serializer_kwargs={ + 'label': _('BOM Item'), + 'source': 'bom_item', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'pricing': False, + 'substitutes': False, + 'sub_part_detail': False, + 'part_detail': False, + 'can_build': False, + }, + default_include=False, prefetch_fields=['bom_item'], ) - assembly_detail = enable_filter( - part_serializers.PartBriefSerializer( - label=_('Assembly'), - source='bom_item.part', - many=False, - read_only=True, - allow_null=True, - pricing=False, - ), - False, + assembly_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'label': _('Assembly'), + 'source': 'bom_item.part', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'pricing': False, + }, + default_include=False, prefetch_fields=['bom_item__part', 'bom_item__part__pricing_data'], ) - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - label=_('Part'), - source='bom_item.sub_part', - many=False, - read_only=True, - allow_null=True, - pricing=False, - ), - False, + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'label': _('Part'), + 'source': 'bom_item.sub_part', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'pricing': False, + }, + default_include=False, prefetch_fields=['bom_item__sub_part', 'bom_item__sub_part__pricing_data'], ) - category_detail = enable_filter( - part_serializers.CategorySerializer( - label=_('Category'), - source='bom_item.sub_part.category', - many=False, - read_only=True, - allow_null=True, - ), - False, + category_detail = OptionalField( + serializer_class=part_serializers.CategorySerializer, + serializer_kwargs={ + 'label': _('Category'), + 'source': 'bom_item.sub_part.category', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'path_detail': False, + }, + default_include=False, prefetch_fields=['bom_item__sub_part__category'], ) - build_detail = enable_filter( - BuildSerializer( - label=_('Build'), - source='build', - many=False, - read_only=True, - allow_null=True, - part_detail=False, - user_detail=False, - project_code_detail=False, - ), - True, + build_detail = OptionalField( + serializer_class=BuildSerializer, + serializer_kwargs={ + 'label': _('Build'), + 'source': 'build', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'part_detail': False, + 'user_detail': False, + 'project_code_detail': False, + }, + default_include=True, ) # Annotated (calculated) fields @@ -1846,46 +1778,3 @@ class BuildConsumeSerializer(serializers.Serializer): raise ValidationError(_('At least one item or line must be provided')) return data - - @transaction.atomic - def save(self): - """Perform the stock consumption step.""" - data = self.validated_data - request = self.context.get('request') - notes = data.get('notes', '') - - # We may be passed either a list of BuildItem or BuildLine instances - items = data.get('items', []) - lines = data.get('lines', []) - - with transaction.atomic(): - # Process the provided BuildItem objects - for item in items: - build_item = item['build_item'] - quantity = item['quantity'] - - if build_item.install_into: - # If the build item is tracked into an output, we do not consume now - # Instead, it gets consumed when the output is completed - continue - - # Offload a background task to consume this BuildItem - offload_task( - consume_build_item, - build_item.pk, - quantity, - notes=notes, - user_id=request.user.pk if request else None, - ) - - # Process the provided BuildLine objects - for line in lines: - build_line = line['build_line'] - - # Offload a background task to consume this BuildLine - offload_task( - consume_build_line, - build_line.pk, - notes=notes, - user_id=request.user.pk if request else None, - ) diff --git a/src/backend/InvenTree/build/tasks.py b/src/backend/InvenTree/build/tasks.py index fd8e3da1de..0dcac04bb8 100644 --- a/src/backend/InvenTree/build/tasks.py +++ b/src/backend/InvenTree/build/tasks.py @@ -2,8 +2,10 @@ from datetime import timedelta from decimal import Decimal +from typing import Optional from django.contrib.auth.models import User +from django.db import transaction from django.utils.translation import gettext_lazy as _ import structlog @@ -27,61 +29,53 @@ def auto_allocate_build(build_id: int, **kwargs): """Run auto-allocation for a specified BuildOrder.""" from build.models import Build - build_order = Build.objects.filter(pk=build_id).first() - - if not build_order: - logger.warning( - 'Could not auto-allocate BuildOrder <%s> - BuildOrder does not exist', - build_id, - ) - return - + build_order = Build.objects.get(pk=build_id) build_order.auto_allocate_stock(**kwargs) -@tracer.start_as_current_span('consume_build_item') -def consume_build_item( - item_id: str, quantity, notes: str = '', user_id: int | None = None +@tracer.start_as_current_span('consume_build_stock') +def consume_build_stock( + build_id: int, + lines: Optional[list[int]] = None, + items: Optional[dict] = None, + user_id: int | None = None, + **kwargs, ): - """Consume stock against a particular BuildOrderLineItem allocation.""" - from build.models import BuildItem + """Consume stock for the specified BuildOrder. - item = BuildItem.objects.filter(pk=item_id).first() + Arguments: + build_id: The ID of the BuildOrder to consume stock for + lines: Optional list of BuildLine IDs to consume + 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 - if not item: - logger.warning( - 'Could not consume stock for BuildItem <%s> - BuildItem does not exist', - item_id, - ) - return + build = Build.objects.get(pk=build_id) + user = User.objects.filter(pk=user_id).first() if user_id else None - item.complete_allocation( - quantity=quantity, - notes=notes, - user=User.objects.filter(pk=user_id).first() if user_id else None, - ) + lines = lines or [] + 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 + ) -@tracer.start_as_current_span('consume_build_line') -def consume_build_line(line_id: int, notes: str = '', user_id: int | None = None): - """Consume stock against a particular BuildOrderLineItem.""" - from build.models import BuildLine - - line_item = BuildLine.objects.filter(pk=line_id).first() - - if not line_item: - logger.warning( - 'Could not consume stock for LineItem <%s> - LineItem does not exist', - line_id, - ) - return - - for item in line_item.allocations.all(): - item.complete_allocation( - quantity=item.quantity, - notes=notes, - user=User.objects.filter(pk=user_id).first() if user_id else None, - ) + # 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 + ) @tracer.start_as_current_span('complete_build_allocations') @@ -89,7 +83,7 @@ def complete_build_allocations(build_id: int, user_id: int): """Complete build allocations for a specified BuildOrder.""" from build.models import Build - build_order = Build.objects.filter(pk=build_id).first() + build_order = Build.objects.get(pk=build_id) if user_id: try: @@ -103,16 +97,217 @@ def complete_build_allocations(build_id: int, user_id: int): else: user = None - if not build_order: - logger.warning( - 'Could not complete build allocations for BuildOrder <%s> - BuildOrder does not exist', - build_id, - ) - return - build_order.complete_allocations(user) +@tracer.start_as_current_span('delete_build_outputs') +def delete_build_outputs(build_id: int, output_ids: list, **kwargs): + """Delete (cancel) specified build outputs for a BuildOrder. + + Arguments: + build_id: The ID of the BuildOrder + output_ids: List of StockItem PKs to delete + """ + from build.models import Build + from stock.models import StockItem + + build = Build.objects.get(pk=build_id) + + with transaction.atomic(): + for output_id in output_ids: + output = StockItem.objects.filter(pk=output_id).first() + if output: + build.delete_output(output) + + +@tracer.start_as_current_span('scrap_build_outputs') +def scrap_build_outputs( + build_id: int, + outputs: list, + location_id: int, + notes: str = '', + discard_allocations: bool = False, + user_id: int | None = None, + **kwargs, +): + """Scrap specified build outputs for a BuildOrder. + + Arguments: + build_id: The ID of the BuildOrder + outputs: List of dicts with 'output_id' and 'quantity' + location_id: PK of the destination StockLocation + notes: Reason for scrapping + discard_allocations: If True, discard (not consume) allocations + user_id: PK of the user initiating the action + """ + from build.models import Build + from stock.models import StockItem, StockLocation + + build = Build.objects.get(pk=build_id) + location = StockLocation.objects.get(pk=location_id) + user = User.objects.filter(pk=user_id).first() if user_id else None + + 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, + ) + + +@tracer.start_as_current_span('complete_build_outputs') +def complete_build_outputs( + build_id: int, + outputs: list, + location_id: int | None, + status: int, + notes: str = '', + user_id: int | None = None, + **kwargs, +): + """Complete specified build outputs for a BuildOrder. + + Arguments: + build_id: The ID of the BuildOrder + outputs: List of dicts with 'output_id' and optional 'quantity' + location_id: PK of the destination StockLocation (or None) + status: Stock status code to assign to completed outputs + notes: Completion notes + user_id: PK of the user initiating the action + """ + from build.models import Build + from stock.models import StockItem, StockLocation + + build = Build.objects.get(pk=build_id) + location = ( + StockLocation.objects.filter(pk=location_id).first() if location_id else None + ) + user = User.objects.filter(pk=user_id).first() if user_id else None + + required_tests = build.part.getRequiredTests() + + 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, + ) + + +@tracer.start_as_current_span('cancel_build') +def cancel_build( + build_id: int, + user_id: int, + remove_allocated_stock: bool = False, + remove_incomplete_outputs: bool = False, +): + """Tasks to run after a BuildOrder is cancelled. + + Arguments: + build_id: The ID of the BuildOrder which has been cancelled + user_id: The ID of the user who cancelled the BuildOrder + remove_allocated_stock: If True, consume any allocated stock + remove_incomplete_outputs: If True, delete any incomplete build outputs + + """ + from build.models import Build + + build = Build.objects.get(pk=build_id) + + if remove_allocated_stock: + complete_build_allocations(build_id, user_id) + else: + build.allocated_stock.all().delete() + + if remove_incomplete_outputs: + build.build_outputs.filter(is_building=True).delete() + + # Notify users that the order has been canceled + InvenTree.helpers_model.notify_responsible( + build, + Build, + exclude=build.issued_by, + content=common.notifications.InvenTreeNotificationBodies.OrderCanceled, + extra_users=build.part.get_subscribers(), + ) + + trigger_event(BuildEvents.CANCELLED, id=build.pk) + + +@tracer.start_as_current_span('complete_build') +def complete_build(build_id: int, user_id: int, trim_allocated_stock: bool = False): + """Tasks to run after a BuildOrder is completed. + + Arguments: + build_id: The ID of the BuildOrder which has been completed + user_id: The ID of the user who completed the BuildOrder + trim_allocated_stock: If True, trim any allocated stock which was not consumed + """ + from build.models import Build + + build = Build.objects.get(pk=build_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) + + # Register an event + trigger_event(BuildEvents.COMPLETED, id=build.pk) + + # Notify users that this build has been completed + targets = [build.issued_by, build.responsible] + + # Also inform anyone subscribed to the assembly part + targets.extend(build.part.get_subscribers()) + + # Notify those users interested in the parent build + if build.parent: + targets.append(build.parent.issued_by) + targets.append(build.parent.responsible) + + # Notify users if this build points to a sales order + if build.sales_order: + targets.append(build.sales_order.created_by) + targets.append(build.sales_order.responsible) + + name = _(f'Build order {build} has been completed') + + context = { + 'build': build, + 'name': name, + 'slug': 'build.completed', + 'message': _('A build order has been completed'), + 'link': InvenTree.helpers_model.construct_absolute_url( + build.get_absolute_url() + ), + 'template': {'html': 'email/build_order_completed.html', 'subject': name}, + } + + common.notifications.trigger_notification( + build, + 'build.completed', + targets=targets, + context=context, + target_exclude=[user], + ) + + @tracer.start_as_current_span('update_build_order_lines') def update_build_order_lines(bom_item_pk: int): """Update all BuildOrderLineItem objects which reference a particular BomItem. diff --git a/src/backend/InvenTree/build/test_api.py b/src/backend/InvenTree/build/test_api.py index 7dacc2ed85..9cd8427c9b 100644 --- a/src/backend/InvenTree/build/test_api.py +++ b/src/backend/InvenTree/build/test_api.py @@ -9,6 +9,7 @@ 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 @@ -154,7 +155,7 @@ class BuildTest(BuildAPITest): self.post( reverse('api-build-output-complete', kwargs={'pk': 99999}), {}, - expected_code=400, + expected_code=404, ) data = self.post(self.url, {}, expected_code=400).data @@ -225,8 +226,8 @@ class BuildTest(BuildAPITest): 'location': 1, 'status': StockStatus.ATTENTION.value, }, - expected_code=201, - max_query_count=400, + expected_code=200, + max_query_count=450, ) self.assertEqual(self.build.incomplete_outputs.count(), 0) @@ -445,7 +446,7 @@ class BuildTest(BuildAPITest): self.post( delete_url, {'outputs': [{'output': output.pk} for output in outputs[1:3]]}, - expected_code=201, + expected_code=200, ) # Two build outputs have been removed @@ -472,7 +473,7 @@ class BuildTest(BuildAPITest): 'outputs': [{'output': output.pk} for output in outputs[3:]], 'location': 4, }, - expected_code=201, + expected_code=200, ) # Check that the outputs have been completed @@ -568,6 +569,9 @@ class BuildTest(BuildAPITest): self.assertEqual(bo.children.count(), 0) + self.assertIsNotNone(bo.issued_by) + self.assertEqual(bo.issued_by, self.user) + class BuildAllocationTest(BuildAPITest): """Unit tests for allocation of stock items against a build order. @@ -970,12 +974,12 @@ class BuildAllocationTest(BuildAPITest): url = reverse('api-build-auto-allocate', kwargs={'pk': build.pk}) # Allocate only 'untracked' items - this should not allocate our tracked item - self.post(url, data={'item_type': 'untracked'}) + self.post(url, data={'item_type': 'untracked'}, expected_code=200) self.assertEqual(N, BuildItem.objects.count()) # Allocate 'tracked' items - this should allocate our tracked item - self.post(url, data={'item_type': 'tracked'}) + self.post(url, data={'item_type': 'tracked'}, expected_code=200) # A new BuildItem should have been created self.assertEqual(N + 1, BuildItem.objects.count()) @@ -1162,18 +1166,12 @@ class BuildListTest(BuildAPITest): data = self.options(self.url, expected_code=200).data self.assertEqual(data['name'], 'Build List') - actions = data['actions']['POST'] + actions = data['actions']['GET'] - for field_name in [ - 'pk', - 'title', - 'part', - 'part_detail', - 'project_code', - 'project_code_detail', - 'quantity', - ]: + for field_name in ['pk', 'title', 'part', 'project_code', 'quantity']: + # Fields should exist in both GET and POST actions self.assertIn(field_name, actions) + self.assertIn(field_name, data['actions']['POST']) # Specific checks for certain fields for field_name in ['part', 'project_code', 'take_from']: @@ -1355,7 +1353,7 @@ class BuildOutputCreateTest(BuildAPITest): url, data={'quantity': 5, 'serial_numbers': '1,2,3-5'}, expected_code=201 ) - # Build outputs have incdeased + # Build outputs have increased self.assertEqual(n_outputs + 5, build.output_count) # Stock items have increased @@ -1468,7 +1466,7 @@ class BuildOutputScrapTest(BuildAPITest): 'location': 1, 'notes': 'Should succeed', }, - expected_code=201, + expected_code=200, ) # There should still be three outputs associated with this build @@ -1536,7 +1534,7 @@ class BuildOutputScrapTest(BuildAPITest): # Partially complete the output (with a valid quantity) data['outputs'][0]['quantity'] = 4 - self.post(url, data, expected_code=201) + self.post(url, data, expected_code=200) build.refresh_from_db() output.refresh_from_db() @@ -1551,6 +1549,53 @@ class BuildOutputScrapTest(BuildAPITest): self.assertFalse(completed_output.is_building) +class BuildOutputCancelTest(BuildAPITest): + """Test cancellation of build outputs.""" + + def test_cancel_output(self): + """Test cancellation of a build output.""" + build = Build.objects.get(pk=1) + build.part.trackable = True + build.part.save() + + N = build.build_outputs.count() + + # Create outputs + outputs = build.create_build_output(2, serials=['101', '202']) + self.assertEqual(outputs.count(), 2) + self.assertEqual(build.build_outputs.count(), N + 2) + + output_ids = list(outputs.values_list('pk', flat=True)) + + # Let's cancel one of the outputs + set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', True) + url = reverse('api-build-output-delete', kwargs={'pk': build.pk}) + + self.post(url, data={'outputs': [{'output': output_ids[0]}]}, expected_code=200) + + # Prevent deletion of serialized stock items, and try again + # Note that this should still succeed, independent of the global setting + set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', False) + + response = self.post( + url, data={'outputs': [{'output': output_ids[1]}]}, expected_code=200 + ) + + # Response should be the task info - the cancellation is performed asynchronously + self.assertIn('task_id', response.data) + self.assertFalse(response.data['exists']) + self.assertFalse(response.data['pending']) + self.assertTrue(response.data['complete']) + self.assertTrue(response.data['success']) + + # The outputs should have been scrapped + self.assertEqual(build.build_outputs.count(), N) + + for pk in output_ids: + self.assertFalse(StockItem.objects.filter(pk=pk).exists()) + self.get(reverse('api-stock-detail', kwargs={'pk': pk}), expected_code=404) + + class BuildLineTests(BuildAPITest): """Unit tests for the BuildLine API endpoints.""" @@ -1564,12 +1609,13 @@ class BuildLineTests(BuildAPITest): # Filter by 'available' status # Note: The max_query_time is bumped up here, as postgresql backend has some strange issues (only during testing) - response = self.get(url, data={'available': True}, max_query_time=15) + # TODO: This needs to be addressed in the future, as 25 seconds is an unacceptably long time for a query to take in testing + response = self.get(url, data={'available': True}, max_query_time=25) n_t = len(response.data) self.assertGreater(n_t, 0) # Note: The max_query_time is bumped up here, as postgresql backend has some strange issues (only during testing) - response = self.get(url, data={'available': False}, max_query_time=15) + response = self.get(url, data={'available': False}, max_query_time=25) n_f = len(response.data) self.assertGreater(n_f, 0) @@ -1735,7 +1781,7 @@ class BuildConsumeTest(BuildAPITest): 'lines': [{'build_line': line.pk} for line in self.build.build_lines.all()] } - self.post(url, data, expected_code=201) + self.post(url, data, expected_code=200) self.assertEqual(self.build.allocated_stock.count(), 0) self.assertEqual(self.build.consumed_stock.count(), 3) @@ -1758,7 +1804,7 @@ class BuildConsumeTest(BuildAPITest): ] } - self.post(url, data, expected_code=201) + self.post(url, data, expected_code=200) self.assertEqual(self.build.allocated_stock.count(), 0) self.assertEqual(self.build.consumed_stock.count(), 3) diff --git a/src/backend/InvenTree/build/test_build.py b/src/backend/InvenTree/build/test_build.py index 608bff91b4..5c571252ec 100644 --- a/src/backend/InvenTree/build/test_build.py +++ b/src/backend/InvenTree/build/test_build.py @@ -27,6 +27,7 @@ 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.status_codes import StockStatus from users.models import Owner logger = structlog.get_logger('inventree') @@ -557,14 +558,29 @@ class BuildTest(BuildTestBase): bo.clean() def test_cancel(self): - """Test cancellation of the build.""" - # TODO - """ - self.allocate_stock(50, 50, 200, self.output_1) - self.build.cancel_build(None) + """Test build cancellation: status is updated and allocations are removed by default.""" + self.build.issue_build() - self.assertEqual(BuildItem.objects.count(), 0) - """ + self.allocate_stock(None, {self.stock_1_2: 50}) + self.assertGreater(self.build.allocated_stock.count(), 0) + + initial_output_count = self.build.build_outputs.filter(is_building=True).count() + self.assertGreater(initial_output_count, 0) + + self.build.cancel_build(None) + self.build.refresh_from_db() + + self.assertEqual(self.build.status, BuildStatus.CANCELLED) + + # Allocations removed (but stock not consumed) by default + self.assertEqual(self.build.allocated_stock.count(), 0) + self.assertIsNone(StockItem.objects.get(pk=self.stock_1_2.pk).consumed_by) + + # Incomplete outputs preserved by default (remove_incomplete_outputs=False) + self.assertEqual( + self.build.build_outputs.filter(is_building=True).count(), + initial_output_count, + ) def test_complete(self): """Test completion of a build output.""" @@ -932,7 +948,10 @@ class ExternalBuildTest(InvenTreeAPITestCase): def test_validation(self): """Test validation of external build logic.""" part = Part.objects.create( - name='Test part', description='A test part', purchaseable=False + name='Test part', + description='A test part', + assembly=True, + purchaseable=False, ) # Create a build order @@ -949,6 +968,47 @@ class ExternalBuildTest(InvenTreeAPITestCase): str(err.exception.messages), ) + def test_build_requirement(self): + """Test the global 'BUILDORDER_EXTERNAL_REQUIRED' setting.""" + # Create required test data + part = Part.objects.create( + name='Test part', + description='A test part', + assembly=True, + purchaseable=True, + ) + supplier = company.models.Company.objects.create( + name='Test supplier', active=True, is_supplier=True + ) + supplier_part = company.models.SupplierPart.objects.create( + part=part, supplier=supplier, SKU='TEST-123' + ) + + po = PurchaseOrder.objects.create(supplier=supplier, reference='PO-9999') + po_line = PurchaseOrderLineItem.objects.create( + order=po, part=supplier_part, quantity=10 + ) + + set_global_setting('BUILDORDER_EXTERNAL_REQUIRED', False) + po_line.clean() # Should not raise an error + + set_global_setting('BUILDORDER_EXTERNAL_BUILDS', True) + set_global_setting('BUILDORDER_EXTERNAL_REQUIRED', True) + + # Expect failure, there is no linked build order + with self.assertRaises(ValidationError): + po_line.clean() + + # Create and link a build order + build = Build.objects.create( + part=part, title='Test build order', quantity=10, external=True + ) + po_line.build_order = build + po_line.save() + + # Clean step now passes + po_line.clean() + def test_logic(self): """Test external build logic.""" # Create a purchaseable assembly part @@ -1063,3 +1123,276 @@ class ExternalBuildTest(InvenTreeAPITestCase): # Filter by 'not external' response = self.get(url, {'external': 'false'}) self.assertEqual(len(response.data), 2) + + +class BuildTaskTests(BuildTestBase): + """Direct unit tests for the background task functions in build/tasks.py. + + These tests call task functions directly (synchronously) to verify the + business logic they encapsulate, independently of the API and offload mechanism. + """ + + def setUp(self): + """Create a stock location available to all task tests.""" + super().setUp() + self.location = StockLocation.objects.create(name='Task Test Location') + + def allocate_stock(self, output, allocations): + """Create BuildItem allocations against self.build for the given output.""" + items_to_create = [] + for item, quantity in allocations.items(): + line = BuildLine.objects.filter( + build=self.build, bom_item__sub_part=item.part + ).first() + items_to_create.append( + BuildItem( + build_line=line, + stock_item=item, + quantity=quantity, + install_into=output, + ) + ) + BuildItem.objects.bulk_create(items_to_create) + + def _setup_complete_build(self): + """Helper: allocate stock fully and complete all outputs so the build is ready to complete.""" + 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 untracked parts + self.allocate_stock( + None, {self.stock_1_1: 50, self.stock_1_2: 10, self.stock_2_1: 30} + ) + # Allocate tracked parts to each output + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + self.allocate_stock(self.output_2, {self.stock_3_1: 14}) + + self.build.complete_build_output(self.output_1, None) + self.build.complete_build_output(self.output_2, None) + + # ----------------------------------------------------------------------- + # cancel_build task + # ----------------------------------------------------------------------- + + def test_cancel_task_discards_allocations(self): + """cancel_build with remove_allocated_stock=False: allocations deleted, stock not consumed.""" + self.build.issue_build() + self.allocate_stock(None, {self.stock_1_2: 50}) + self.assertGreater(self.build.allocated_stock.count(), 0) + + build.tasks.cancel_build( + self.build.pk, self.user.pk, remove_allocated_stock=False + ) + + # BuildItem rows gone + self.assertEqual(self.build.allocated_stock.count(), 0) + # Stock item was NOT consumed + self.assertIsNone(StockItem.objects.get(pk=self.stock_1_2.pk).consumed_by) + + def test_cancel_task_consumes_allocations(self): + """cancel_build with remove_allocated_stock=True: stock items are marked consumed.""" + self.build.issue_build() + self.allocate_stock(None, {self.stock_1_2: 50}) + + build.tasks.cancel_build( + self.build.pk, self.user.pk, remove_allocated_stock=True + ) + + # All BuildItem rows gone + self.assertEqual(self.build.allocated_stock.count(), 0) + # The allocated (non-trackable) stock was consumed + self.assertGreater(self.build.consumed_stock.count(), 0) + + def test_cancel_task_removes_incomplete_outputs(self): + """cancel_build with remove_incomplete_outputs=True: in-progress outputs are deleted.""" + self.build.issue_build() + initial_count = self.build.build_outputs.filter(is_building=True).count() + self.assertGreater(initial_count, 0) + + build.tasks.cancel_build( + self.build.pk, self.user.pk, remove_incomplete_outputs=True + ) + + self.assertEqual(self.build.build_outputs.filter(is_building=True).count(), 0) + + def test_cancel_task_preserves_incomplete_outputs(self): + """cancel_build with remove_incomplete_outputs=False: in-progress outputs are kept.""" + self.build.issue_build() + initial_count = self.build.build_outputs.filter(is_building=True).count() + self.assertGreater(initial_count, 0) + + build.tasks.cancel_build( + self.build.pk, self.user.pk, remove_incomplete_outputs=False + ) + + self.assertEqual( + self.build.build_outputs.filter(is_building=True).count(), initial_count + ) + + # ----------------------------------------------------------------------- + # complete_build task + # ----------------------------------------------------------------------- + + @override_settings( + TESTING_TABLE_EVENTS=True, + PLUGIN_TESTING_EVENTS=True, + PLUGIN_TESTING_EVENTS_ASYNC=True, + ) + def test_complete_build_task_triggers_event(self): + """complete_build task fires the BuildEvents.COMPLETED event.""" + from django_q.models import OrmQ + + from build.events import BuildEvents + + set_global_setting('ENABLE_PLUGINS_EVENTS', True) + OrmQ.objects.all().delete() + + self._setup_complete_build() + self.build.complete_build(self.user) + + task = findOffloadedEvent(BuildEvents.COMPLETED, matching_kwargs=['id']) + self.assertIsNotNone(task) + self.assertEqual(task.kwargs()['id'], self.build.pk) + + set_global_setting('ENABLE_PLUGINS_EVENTS', False) + + def test_complete_build_task_trim_stock(self): + """complete_build with trim_allocated_stock=True removes over-allocations before consuming.""" + self.stock_1_2.quantity = 100 + self.stock_1_2.save() + self.stock_2_1.quantity = 30 + self.stock_2_1.save() + + self.build.issue_build() + + # Over-allocate sub_part_1: need 50, allocate 100 + self.allocate_stock(None, {self.stock_1_2: 100, self.stock_2_1: 30}) + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + self.allocate_stock(self.output_2, {self.stock_3_1: 14}) + + self.assertTrue(self.build.is_overallocated()) + + self.build.complete_build_output(self.output_1, None) + self.build.complete_build_output(self.output_2, None) + self.assertTrue(self.build.can_complete) + + self.build.complete_build(self.user, trim_allocated_stock=True) + self.build.refresh_from_db() + self.assertEqual(self.build.status, BuildStatus.COMPLETE) + + # Only 50 units of sub_part_1 should have been consumed (not 100) + consumed_qty = StockItem.objects.filter( + consumed_by=self.build, part=self.sub_part_1 + ).aggregate(total=Sum('quantity'))['total'] + self.assertEqual(consumed_qty, 50) + + # ----------------------------------------------------------------------- + # delete_build_outputs task + # ----------------------------------------------------------------------- + + def test_delete_build_outputs_skips_missing_id(self): + """delete_build_outputs silently skips nonexistent output IDs and deletes valid ones.""" + from build.tasks import delete_build_outputs + + # Create an output directly to avoid serial-number requirements on the trackable assembly + output = StockItem.objects.create( + part=self.assembly, quantity=3, is_building=True, build=self.build + ) + real_id = output.pk + + # Mix a valid ID with a nonexistent one — must not raise + delete_build_outputs(self.build.pk, [real_id, 99999]) + + self.assertFalse(StockItem.objects.filter(pk=real_id).exists()) + + # ----------------------------------------------------------------------- + # scrap_build_outputs task + # ----------------------------------------------------------------------- + + def test_scrap_build_outputs_discard_allocations(self): + """scrap_build_outputs with discard_allocations=True removes allocations without consuming stock.""" + from build.tasks import scrap_build_outputs + + self.build.issue_build() + # Allocate tracked stock to output_1 + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + self.assertGreater(self.output_1.items_to_install.count(), 0) + + scrap_build_outputs( + self.build.pk, + [{'output_id': self.output_1.pk, 'quantity': self.output_1.quantity}], + location_id=self.location.pk, + notes='discard test', + discard_allocations=True, + user_id=None, + ) + + self.output_1.refresh_from_db() + self.assertEqual(self.output_1.status, StockStatus.REJECTED.value) + self.assertFalse(self.output_1.is_building) + + # Allocation rows should be gone + self.assertEqual(self.output_1.items_to_install.count(), 0) + # Stock was discarded (not consumed or installed) + self.stock_3_1.refresh_from_db() + self.assertIsNone(self.stock_3_1.consumed_by) + self.assertIsNone(self.stock_3_1.belongs_to) + + def test_scrap_build_outputs_consume_allocations(self): + """scrap_build_outputs with discard_allocations=False (default) consumes/installs stock.""" + from build.tasks import scrap_build_outputs + + self.build.issue_build() + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + + scrap_build_outputs( + self.build.pk, + [{'output_id': self.output_1.pk, 'quantity': self.output_1.quantity}], + location_id=self.location.pk, + notes='consume test', + discard_allocations=False, + user_id=None, + ) + + self.output_1.refresh_from_db() + self.assertEqual(self.output_1.status, StockStatus.REJECTED.value) + self.assertFalse(self.output_1.is_building) + + # complete_allocation splits stock_3_1 and installs the split piece into output_1 + # (stock_3_1 quantity=1000, only 6 allocated, so a child item is created) + self.assertTrue( + StockItem.objects.filter(belongs_to=self.output_1).exists(), + 'Expected a tracked stock item to be installed into the output', + ) + + # ----------------------------------------------------------------------- + # complete_build_outputs task + # ----------------------------------------------------------------------- + + def test_complete_build_outputs_with_status_none(self): + """complete_build_outputs with status=None falls back to StockStatus.OK in the model.""" + from build.tasks import complete_build_outputs + + self.build.issue_build() + # Create output directly to avoid serial-number requirements on the trackable assembly + output = StockItem.objects.create( + part=self.assembly, quantity=5, is_building=True, build=self.build + ) + + complete_build_outputs( + self.build.pk, + [{'output_id': output.pk}], + location_id=self.location.pk, + status=None, + notes='status none test', + user_id=None, + ) + + output.refresh_from_db() + self.assertFalse(output.is_building) + # status=None should resolve to StockStatus.OK (the model default) + self.assertEqual(output.status, StockStatus.OK.value) diff --git a/src/backend/InvenTree/common/admin.py b/src/backend/InvenTree/common/admin.py index a5461b7d02..5703423afc 100644 --- a/src/backend/InvenTree/common/admin.py +++ b/src/backend/InvenTree/common/admin.py @@ -32,6 +32,24 @@ class ParameterAdmin(admin.ModelAdmin): search_fields = ('template__name', 'data', 'note') +class SelectionListEntryInlineAdmin(admin.StackedInline): + """Inline admin class for the SelectionListEntry model.""" + + model = common.models.SelectionListEntry + extra = 0 + + +@admin.register(common.models.SelectionList) +class SelectionListAdmin(admin.ModelAdmin): + """Admin interface for SelectionList objects.""" + + list_display = ('name', 'description', 'active', 'locked') + search_fields = ('name', 'description') + list_filter = ('active', 'locked') + + inlines = [SelectionListEntryInlineAdmin] + + @admin.register(common.models.Attachment) class AttachmentAdmin(admin.ModelAdmin): """Admin interface for Attachment objects.""" diff --git a/src/backend/InvenTree/common/api.py b/src/backend/InvenTree/common/api.py index 923a24b485..2f3d0b59f2 100644 --- a/src/backend/InvenTree/common/api.py +++ b/src/backend/InvenTree/common/api.py @@ -17,14 +17,20 @@ from django.views.decorators.csrf import csrf_exempt import django_filters.rest_framework.filters as rest_filters import django_q.models +import django_q.tasks from django_filters.rest_framework.filterset import FilterSet -from django_q.tasks import async_task from djmoney.contrib.exchange.models import ExchangeBackend, Rate -from drf_spectacular.utils import OpenApiResponse, extend_schema +from drf_spectacular.utils import ( + OpenApiParameter, + OpenApiResponse, + extend_schema, + extend_schema_view, +) from error_report.models import Error from opentelemetry import trace from pint._typing import UnitLike -from rest_framework import generics, serializers +from rest_framework import serializers, viewsets +from rest_framework.decorators import action from rest_framework.exceptions import NotAcceptable, NotFound, PermissionDenied from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.response import Response @@ -44,16 +50,18 @@ from generic.states.api import urlpattern as generic_states_api_urls from InvenTree.api import ( BulkCreateMixin, BulkDeleteMixin, + BulkDeleteViewsetMixin, GenericMetadataView, SimpleGenericMetadataView, ) from InvenTree.config import CONFIG_LOOKUPS -from InvenTree.filters import ( - ORDER_FILTER, - SEARCH_ORDER_FILTER, - SEARCH_ORDER_FILTER_ALIAS, -) +from InvenTree.filters import ORDER_FILTER, SEARCH_ORDER_FILTER from InvenTree.helpers import inheritors, str2bool +from InvenTree.helpers_api import ( + InvenTreeApiRouter, + RetrieveDestroyModelViewSet, + RetrieveUpdateDestroyModelViewSet, +) from InvenTree.helpers_email import send_email from InvenTree.mixins import ( CreateAPI, @@ -61,7 +69,6 @@ from InvenTree.mixins import ( ListCreateAPI, OutputOptionsMixin, RetrieveAPI, - RetrieveDestroyAPI, RetrieveUpdateAPI, RetrieveUpdateDestroyAPI, ) @@ -74,6 +81,10 @@ from InvenTree.permissions import ( IsSuperuserOrSuperScope, UserSettingsPermissionsOrScope, ) +from InvenTree.serializers import EmptySerializer + +admin_router = InvenTreeApiRouter() +common_router = InvenTreeApiRouter() class CsrfExemptMixin: @@ -118,7 +129,7 @@ class WebhookView(CsrfExemptMixin, APIView): # process data message = self.webhook.save_data(payload, headers, request) if self.run_async: - async_task(self._process_payload, message.id) + django_q.tasks.async_task(self._process_payload, message.id) else: self._process_result( self.webhook.process_payload(message, payload, headers), message @@ -158,14 +169,18 @@ class WebhookView(CsrfExemptMixin, APIView): raise NotFound() -class CurrencyExchangeView(APIView): - """API endpoint for displaying currency information.""" +class CurrencyViewSet(viewsets.GenericViewSet): + """Viewset for currency exchange information.""" permission_classes = [IsAuthenticatedOrReadScope] - serializer_class = None + serializer_class = EmptySerializer - @extend_schema(responses={200: common.serializers.CurrencyExchangeSerializer}) - def get(self, request, fmt=None): + @action( + detail=False, + methods=['get'], + serializer_class=common.serializers.CurrencyExchangeSerializer, + ) + def exchange(self, request, fmt=None): """Return information on available currency conversions.""" # Extract a list of all available rates try: @@ -198,17 +213,12 @@ class CurrencyExchangeView(APIView): return Response(response) - -class CurrencyRefreshView(APIView): - """API endpoint for manually refreshing currency exchange rates. - - User must be a 'staff' user to access this endpoint - """ - - permission_classes = [IsAuthenticatedOrReadScope, IsAdminUser] - serializer_class = None - - def post(self, request, *args, **kwargs): + @action( + detail=False, + methods=['post'], + permission_classes=[IsAuthenticatedOrReadScope, IsAdminUser], + ) + def refresh(self, request, *args, **kwargs): """Performing a POST request will update currency exchange rates.""" from InvenTree.tasks import update_exchange_rates @@ -217,6 +227,9 @@ class CurrencyRefreshView(APIView): return Response({'success': 'Exchange rates updated'}) +common_router.register('currency', CurrencyViewSet, basename='api-currency') + + class SettingsList(ListAPI): """Generic ListView for settings. @@ -328,13 +341,23 @@ class UserSettingsDetail(RetrieveUpdateAPI): ) -class NotificationMessageMixin: - """Generic mixin for NotificationMessage.""" +class NotificationMessageViewSet( + BulkDeleteViewsetMixin, RetrieveUpdateDestroyModelViewSet +): + """Notifications for the current user. + + - User can only view / delete their own notification objects + """ queryset = common.models.NotificationMessage.objects.all() serializer_class = common.serializers.NotificationMessageSerializer permission_classes = [UserSettingsPermissionsOrScope] + filter_backends = SEARCH_ORDER_FILTER + ordering_fields = ['category', 'name', 'read', 'creation'] + search_fields = ['name', 'message'] + filterset_fields = ['category', 'read'] + def get_queryset(self): """Return prefetched queryset.""" queryset = ( @@ -351,20 +374,6 @@ class NotificationMessageMixin: return queryset - -class NotificationList(NotificationMessageMixin, BulkDeleteMixin, ListAPI): - """List view for all notifications of the current user.""" - - permission_classes = [IsAuthenticatedOrReadScope] - - filter_backends = SEARCH_ORDER_FILTER - - ordering_fields = ['category', 'name', 'read', 'creation'] - - search_fields = ['name', 'message'] - - filterset_fields = ['category', 'read'] - def filter_queryset(self, queryset): """Only list notifications which apply to the current user.""" try: @@ -385,18 +394,10 @@ class NotificationList(NotificationMessageMixin, BulkDeleteMixin, ListAPI): queryset = queryset.filter(user=request.user) return queryset - -class NotificationDetail(NotificationMessageMixin, RetrieveUpdateDestroyAPI): - """Detail view for an individual notification object. - - - User can only view / delete their own notification objects - """ - - -class NotificationReadAll(NotificationMessageMixin, RetrieveAPI): - """API endpoint to mark all notifications as read.""" - - def get(self, request, *args, **kwargs): + @action( + detail=False, methods=['post'], permission_classes=[IsAuthenticatedOrReadScope] + ) + def readall(self, request, *args, **kwargs): """Set all messages for the current user as read.""" try: self.queryset.filter(user=request.user, read=False).update(read=True) @@ -407,47 +408,50 @@ class NotificationReadAll(NotificationMessageMixin, RetrieveAPI): ) -class NewsFeedMixin: - """Generic mixin for NewsFeedEntry.""" +common_router.register( + 'notifications', NotificationMessageViewSet, basename='api-notifications' +) + + +class NewsFeedViewSet(BulkDeleteViewsetMixin, RetrieveUpdateDestroyModelViewSet): + """Newsfeed from the official inventree.org website.""" queryset = common.models.NewsFeedEntry.objects.all() serializer_class = common.serializers.NewsFeedEntrySerializer permission_classes = [IsAdminOrAdminScope] - -class NewsFeedEntryList(NewsFeedMixin, BulkDeleteMixin, ListAPI): - """List view for all news items.""" - filter_backends = ORDER_FILTER - ordering = '-published' - ordering_fields = ['published', 'author', 'read'] - filterset_fields = ['read'] -class NewsFeedEntryDetail(NewsFeedMixin, RetrieveUpdateDestroyAPI): - """Detail view for an individual news feed object.""" +common_router.register('news', NewsFeedViewSet, basename='api-news') -class ConfigList(ListAPI): - """List view for all accessed configurations.""" +@extend_schema_view( + retrieve=extend_schema( + parameters=[ + OpenApiParameter( + name='key', + description='Unique identifier for this configuration', + required=True, + location=OpenApiParameter.PATH, + ) + ] + ) +) +class ConfigViewSet(viewsets.ReadOnlyModelViewSet): + """All accessed/in-use configurations.""" queryset = CONFIG_LOOKUPS serializer_class = common.serializers.ConfigSerializer permission_classes = [IsSuperuserOrSuperScope] + lookup_field = 'key' # Specifically disable pagination for this view pagination_class = None - -class ConfigDetail(RetrieveAPI): - """Detail view for an individual configuration.""" - - serializer_class = common.serializers.ConfigSerializer - permission_classes = [IsSuperuserOrSuperScope] - def get_object(self): """Attempt to find a config object with the provided key.""" key = self.kwargs['key'] @@ -457,6 +461,9 @@ class ConfigDetail(RetrieveAPI): return {key: value} +admin_router.register('config', ConfigViewSet, basename='api-config') + + class NotesImageList(ListCreateAPI): """List view for all notes images.""" @@ -496,7 +503,7 @@ class ProjectCodeDetail(RetrieveUpdateDestroyAPI): permission_classes = [IsStaffOrReadOnlyScope] -class CustomUnitList(DataExportViewMixin, ListCreateAPI): +class CustomUnitViewset(DataExportViewMixin, viewsets.ModelViewSet): """List view for custom units.""" queryset = common.models.CustomUnit.objects.all() @@ -504,22 +511,12 @@ class CustomUnitList(DataExportViewMixin, ListCreateAPI): permission_classes = [IsStaffOrReadOnlyScope] filter_backends = SEARCH_ORDER_FILTER - -class CustomUnitDetail(RetrieveUpdateDestroyAPI): - """Detail view for a particular custom unit.""" - - queryset = common.models.CustomUnit.objects.all() - serializer_class = common.serializers.CustomUnitSerializer - permission_classes = [IsStaffOrReadOnlyScope] - - -class AllUnitList(RetrieveAPI): - """List of all defined units.""" - - serializer_class = common.serializers.AllUnitListResponseSerializer - permission_classes = [IsStaffOrReadOnlyScope] - - def get(self, request, *args, **kwargs): + @action( + detail=False, + methods=['get'], + serializer_class=common.serializers.AllUnitListResponseSerializer, + ) + def all(self, request, *args, **kwargs): """Return a list of all available units.""" reg = InvenTree.conversion.get_unit_registry() all_units = {k: self.get_unit(reg, k) for k in reg} @@ -543,7 +540,10 @@ class AllUnitList(RetrieveAPI): } -class ErrorMessageList(BulkDeleteMixin, ListAPI): +common_router.register('units', CustomUnitViewset, basename='api-custom-unit') + + +class ErrorMessageViewSet(BulkDeleteViewsetMixin, RetrieveUpdateDestroyModelViewSet): """List view for server error messages.""" queryset = Error.objects.all() @@ -559,12 +559,20 @@ class ErrorMessageList(BulkDeleteMixin, ListAPI): search_fields = ['info', 'data'] -class ErrorMessageDetail(RetrieveUpdateDestroyAPI): - """Detail view for a single error message.""" +common_router.register('error-report', ErrorMessageViewSet, basename='api-error') - queryset = Error.objects.all() - serializer_class = common.serializers.ErrorMessageSerializer - permission_classes = [IsAuthenticatedOrReadScope, IsAdminUser] + +class BackgroundTaskDetail(APIView): + """Detail view for a single background task.""" + + permission_classes = [IsAuthenticatedOrReadScope] + + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def get(self, request, task_id, *args, **kwargs): + """Fetch information regarding a particular background task ID.""" + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + + return Response(response, status=response['http_status']) class BackgroundTaskOverview(APIView): @@ -573,7 +581,10 @@ class BackgroundTaskOverview(APIView): permission_classes = [IsAuthenticatedOrReadScope, IsAdminUser] serializer_class = None - @extend_schema(responses={200: common.serializers.TaskOverviewSerializer}) + @extend_schema( + operation_id='background_task_overview', + responses={200: common.serializers.TaskOverviewSerializer}, + ) def get(self, request, fmt=None): """Return information about the current status of the background task queue.""" import django_q.models as q_models @@ -611,7 +622,7 @@ class ScheduledTaskList(ListAPI): ordering_fields = ['pk', 'func', 'last_run', 'next_run'] - search_fields = ['func'] + search_fields = ['func', 'name'] def get_queryset(self): """Return annotated queryset.""" @@ -705,7 +716,17 @@ class AttachmentFilter(FilterSet): """Metaclass options.""" model = common.models.Attachment - fields = ['model_type', 'model_id', 'upload_user'] + fields = ['model_type', 'model_id', 'upload_user', 'is_image'] + + has_thumbnail = rest_filters.BooleanFilter( + label=_('Has Thumbnail'), method='filter_has_thumbnail' + ) + + def filter_has_thumbnail(self, queryset, name, value): + """Filter attachments based on whether they have a thumbnail or not.""" + if value: + return queryset.exclude(thumbnail=None).exclude(thumbnail='') + return queryset.filter(Q(thumbnail=None) | Q(thumbnail='')).distinct() is_link = rest_filters.BooleanFilter(label=_('Is Link'), method='filter_is_link') @@ -769,8 +790,34 @@ class AttachmentList(AttachmentMixin, BulkDeleteMixin, ListCreateAPI): class AttachmentDetail(AttachmentMixin, RetrieveUpdateDestroyAPI): """Detail API endpoint for Attachment objects.""" + def update(self, request, *args, **kwargs): + """Update an existing attachment object.""" + attachment = self.get_object() + + if not attachment.check_permission('change', request.user): + raise PermissionDenied( + _('User does not have permission to edit this attachment') + ) + + partial = kwargs.pop('partial', False) + data = self.clean_data(request.data) + + # Extract filename first + filename = data.pop('filename', None) + + # Run other validation / updates first, before attempting to rename the file + serializer = self.get_serializer(attachment, data=data, partial=partial) + serializer.is_valid(raise_exception=True) + self.perform_update(serializer) + + # User is attempting to rename the file + if filename and attachment.basename and filename != attachment.basename: + attachment.rename(filename) + + return Response(serializer.data) + def destroy(self, request, *args, **kwargs): - """Check user permissions before deleting an attachment.""" + """Delete an existing attachment object.""" attachment = self.get_object() if not attachment.check_permission('delete', request.user): @@ -1078,7 +1125,7 @@ class ParameterList( """List API endpoint for Parameter objects.""" filterset_class = ParameterFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_fields = ['name', 'data', 'units', 'template', 'updated', 'updated_by'] @@ -1133,6 +1180,10 @@ class SelectionListDetail(RetrieveUpdateDestroyAPI): 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.""" @@ -1153,42 +1204,57 @@ class EntryMixin: class SelectionEntryList(EntryMixin, ListCreateAPI): """List view for SelectionEntry objects.""" + filter_backends = SEARCH_ORDER_FILTER + + ordering_fields = ['list', 'label', 'active'] + + search_fields = ['label', 'description'] + + filterset_fields = ['active', 'value', 'list'] + class SelectionEntryDetail(EntryMixin, RetrieveUpdateDestroyAPI): """Detail view for a SelectionEntry object.""" -class DataOutputEndpointMixin: +class DataOutputViewSet(BulkDeleteViewsetMixin, RetrieveDestroyModelViewSet): """Mixin class for DataOutput endpoints.""" queryset = common.models.DataOutput.objects.all() serializer_class = common.serializers.DataOutputSerializer permission_classes = [IsAuthenticatedOrReadScope] - -class DataOutputList(DataOutputEndpointMixin, BulkDeleteMixin, ListAPI): - """List view for DataOutput objects.""" - filter_backends = SEARCH_ORDER_FILTER ordering_fields = ['pk', 'user', 'plugin', 'output_type', 'created'] filterset_fields = ['user'] + def get_queryset(self): + """Return the set of DataOutput objects which the user has permission to view.""" + queryset = super().get_queryset() -class DataOutputDetail(DataOutputEndpointMixin, generics.DestroyAPIView, RetrieveAPI): - """Detail view for a DataOutput object.""" + try: + user = self.request.user + except AttributeError: + raise PermissionDenied('User information is not available') + + # Allow staff users access to all DataOutput objects + if user.is_staff: + return queryset + + # All other users are limited to viewing their own DataOutput objects + return queryset.filter(user=user) -class EmailMessageMixin: - """Mixin class for Email endpoints.""" +common_router.register('data-output', DataOutputViewSet, basename='api-data-output') + + +class EmailViewSet(BulkDeleteViewsetMixin, RetrieveDestroyModelViewSet): + """Backend E-Mail management for administrative purposes.""" queryset = common.models.EmailMessage.objects.all() serializer_class = common.serializers.EmailMessageSerializer permission_classes = [IsSuperuserOrSuperScope] - -class EmailMessageList(EmailMessageMixin, BulkDeleteMixin, ListAPI): - """List view for email objects.""" - filter_backends = SEARCH_ORDER_FILTER ordering_fields = [ 'created', @@ -1208,19 +1274,16 @@ class EmailMessageList(EmailMessageMixin, BulkDeleteMixin, ListAPI): 'thread_id_key', ] - -class EmailMessageDetail(EmailMessageMixin, RetrieveDestroyAPI): - """Detail view for an email object.""" - - -class TestEmail(CreateAPI): - """Send a test email.""" - - serializer_class = common.serializers.TestEmailSerializer - permission_classes = [IsSuperuserOrSuperScope] - - def perform_create(self, serializer): + @action( + detail=False, + methods=['post'], + serializer_class=common.serializers.TestEmailSerializer, + ) + def test(self, request): """Send a test email.""" + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data delivered, reason = send_email( @@ -1232,6 +1295,10 @@ class TestEmail(CreateAPI): raise serializers.ValidationError( detail=f'Failed to send test email: "{reason}"' ) # pragma: no cover + return Response(serializer.data) + + +admin_router.register('email', EmailViewSet, basename='api-email') class HealthCheckStatusSerializer(serializers.Serializer): @@ -1399,6 +1466,9 @@ common_api_urls = [ name='api-scheduled-task-list', ), path('failed/', FailedTaskList.as_view(), name='api-failed-task-list'), + path( + '/', BackgroundTaskDetail.as_view(), name='api-task-detail' + ), path('', BackgroundTaskOverview.as_view(), name='api-task-overview'), ]), ), @@ -1433,13 +1503,6 @@ common_api_urls = [ path('', ParameterList.as_view(), name='api-parameter-list'), ]), ), - path( - 'error-report/', - include([ - path('/', ErrorMessageDetail.as_view(), name='api-error-detail'), - path('', ErrorMessageList.as_view(), name='api-error-list'), - ]), - ), # Metadata path( 'metadata/', @@ -1466,72 +1529,6 @@ common_api_urls = [ path('', ProjectCodeList.as_view(), name='api-project-code-list'), ]), ), - # Custom physical units - path( - 'units/', - include([ - path( - '/', - include([ - path('', CustomUnitDetail.as_view(), name='api-custom-unit-detail') - ]), - ), - path('all/', AllUnitList.as_view(), name='api-all-unit-list'), - path('', CustomUnitList.as_view(), name='api-custom-unit-list'), - ]), - ), - # Currencies - path( - 'currency/', - include([ - path( - 'exchange/', - CurrencyExchangeView.as_view(), - name='api-currency-exchange', - ), - path( - 'refresh/', CurrencyRefreshView.as_view(), name='api-currency-refresh' - ), - ]), - ), - # Notifications - path( - 'notifications/', - include([ - # Individual purchase order detail URLs - path( - '/', - include([ - path( - '', - NotificationDetail.as_view(), - name='api-notifications-detail', - ) - ]), - ), - # Read all - path( - 'readall/', - NotificationReadAll.as_view(), - name='api-notifications-readall', - ), - # Notification messages list - path('', NotificationList.as_view(), name='api-notifications-list'), - ]), - ), - # News - path( - 'news/', - include([ - path( - '/', - include([ - path('', NewsFeedEntryDetail.as_view(), name='api-news-detail') - ]), - ), - path('', NewsFeedEntryList.as_view(), name='api-news-list'), - ]), - ), # Flags path( 'flags/', @@ -1561,16 +1558,6 @@ common_api_urls = [ path('icons/', IconList.as_view(), name='api-icon-list'), # Selection lists path('selection/', include(selection_urls)), - # Data output - path( - 'data-output/', - include([ - path( - '/', DataOutputDetail.as_view(), name='api-data-output-detail' - ), - path('', DataOutputList.as_view(), name='api-data-output-list'), - ]), - ), # System APIs (related to basic system functions) path( 'system/', @@ -1591,19 +1578,8 @@ common_api_urls = [ ) ]), ), + # Router + path('', include(common_router.urls)), ] -admin_api_urls = [ - # Admin - path('config/', ConfigList.as_view(), name='api-config-list'), - path('config//', ConfigDetail.as_view(), name='api-config-detail'), - # Email - path( - 'email/', - include([ - path('test/', TestEmail.as_view(), name='api-email-test'), - path('/', EmailMessageDetail.as_view(), name='api-email-detail'), - path('', EmailMessageList.as_view(), name='api-email-list'), - ]), - ), -] +admin_api_urls = admin_router.urls diff --git a/src/backend/InvenTree/common/currency.py b/src/backend/InvenTree/common/currency.py index 87d9f59faa..adb3b55cff 100644 --- a/src/backend/InvenTree/common/currency.py +++ b/src/backend/InvenTree/common/currency.py @@ -230,6 +230,6 @@ def get_price( quantity = decimal.Decimal(f'{quantity}') if pb_found: - cost = pb_cost * quantity + cost = decimal.Decimal(pb_cost) * quantity return InvenTree.helpers.normalize(cost + instance.base_cost) return None diff --git a/src/backend/InvenTree/common/filters.py b/src/backend/InvenTree/common/filters.py index 35b59908ed..c3cff3677d 100644 --- a/src/backend/InvenTree/common/filters.py +++ b/src/backend/InvenTree/common/filters.py @@ -19,6 +19,9 @@ from django.db.models import ( from django.db.models.query import QuerySet from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers +from taggit.serializers import TagListSerializerField + import InvenTree.conversion import InvenTree.helpers import InvenTree.serializers @@ -325,11 +328,15 @@ def enable_project_code_filter(default: bool = True): """ from common.serializers import ProjectCodeSerializer - return InvenTree.serializers.enable_filter( - ProjectCodeSerializer( - source='project_code', many=False, read_only=True, allow_null=True - ), - default, + return InvenTree.serializers.OptionalField( + serializer_class=ProjectCodeSerializer, + serializer_kwargs={ + 'source': 'project_code', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=default, filter_name='project_code_detail', prefetch_fields=['project_code'], ) @@ -344,14 +351,15 @@ def enable_project_label_filter(default: bool = True): If applied, this field will automatically prefetch the 'project_code' relationship. """ - return InvenTree.serializers.enable_filter( - InvenTree.serializers.FilterableCharField( - source='project_code.code', - read_only=True, - label=_('Project Code Label'), - allow_null=True, - ), - default, + return InvenTree.serializers.OptionalField( + serializer_class=serializers.CharField, + serializer_kwargs={ + 'source': 'project_code.code', + 'read_only': True, + 'label': _('Project Code Label'), + 'allow_null': True, + }, + default_include=default, filter_name='project_code_detail', prefetch_fields=['project_code'], ) @@ -369,9 +377,15 @@ def enable_parameters_filter(): """ from common.serializers import ParameterSerializer - return InvenTree.serializers.enable_filter( - ParameterSerializer(many=True, read_only=True, allow_null=True), - False, + return InvenTree.serializers.OptionalField( + serializer_class=ParameterSerializer, + serializer_kwargs={ + 'many': True, + 'read_only': True, + 'allow_null': True, + 'required': False, + }, + default_include=False, filter_name='parameters', prefetch_fields=[ 'parameters_list', @@ -390,11 +404,10 @@ def enable_tags_filter(default: bool = False): If applied, this field will automatically prefetch the 'tags' relationship. """ - from InvenTree.serializers import FilterableTagListField - - return InvenTree.serializers.enable_filter( - FilterableTagListField(required=False), - default, + return InvenTree.serializers.OptionalField( + serializer_class=TagListSerializerField, + serializer_kwargs={'required': False}, + default_include=default, filter_name='tags', prefetch_fields=['tags', 'tagged_items', 'tagged_items__tag'], ) diff --git a/src/backend/InvenTree/common/migrations/0042_attachment_is_image_attachment_thumbnail.py b/src/backend/InvenTree/common/migrations/0042_attachment_is_image_attachment_thumbnail.py new file mode 100644 index 0000000000..d4bf86df20 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0042_attachment_is_image_attachment_thumbnail.py @@ -0,0 +1,48 @@ +# Generated by Django 5.2.14 on 2026-05-18 11:34 + +from django.db import migrations, models + +import common.models +import common.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ("common", "0041_auto_20251203_1244"), + ] + + operations = [ + migrations.AddField( + model_name="attachment", + name="thumbnail", + field=models.ImageField( + blank=True, + help_text="Thumbnail image for this attachment", + null=True, + upload_to="", + verbose_name="Thumbnail", + ), + ), + migrations.AddField( + model_name="attachment", + name="is_image", + field=models.BooleanField( + default=False, + help_text="True if this attachment is a valid image file", + verbose_name="Is image", + ), + ), + migrations.AlterField( + model_name="attachment", + name="attachment", + field=models.FileField( + blank=True, + help_text="Select file to attach", + null=True, + upload_to=common.models.rename_attachment, + validators=[common.validators.validate_attachment_file], + verbose_name="Attachment", + ), + ), + ] diff --git a/src/backend/InvenTree/common/migrations/0043_auto_20260518_1206.py b/src/backend/InvenTree/common/migrations/0043_auto_20260518_1206.py new file mode 100644 index 0000000000..597ad45cf7 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0043_auto_20260518_1206.py @@ -0,0 +1,58 @@ +# Generated by Django 5.2.14 on 2026-05-18 12:06 + +import io +import os + +from PIL import Image +from tqdm import tqdm + +from time import sleep + +from django.db import migrations +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage + + +def update_image_attachments(apps, schema_editor): + """Update existing attachments to ensure that image attachments have thumbnails. + + For each existing attachment, check if it is an image. + If it is, generate a thumbnail for it. + + Note: This function mirrors the logic used in the Attachment model's + check_is_image method, at the time of writing this migration (2026-05-18). + """ + + import common.tasks + + Attachment = apps.get_model('common', 'Attachment') + + # Find all Attachment instances which (potentially) have a file attached + attachments = Attachment.objects.exclude(attachment__isnull=True).exclude(attachment='') + + if attachments.count() == 0: + return + + progress = tqdm(total=attachments.count(), desc='Migration common.0043: Updating attachments') + + for attachment in attachments: + progress.update(1) + + if not attachment.attachment: + continue + + if not attachment.attachment.name or not default_storage.exists(attachment.attachment.name): + continue + + common.tasks.rebuild_attachment(attachment.pk) + + +class Migration(migrations.Migration): + + dependencies = [ + ("common", "0042_attachment_is_image_attachment_thumbnail"), + ] + + operations = [ + migrations.RunPython(update_image_attachments, reverse_code=migrations.RunPython.noop), + ] diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index a2246343a4..a53d2640b4 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -10,10 +10,12 @@ import json import math import os import uuid +from collections import OrderedDict from datetime import timedelta, timezone from email.utils import make_msgid from enum import Enum from io import BytesIO +from pathlib import Path from secrets import compare_digest from typing import Any, Optional @@ -24,9 +26,10 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.contrib.humanize.templatetags.humanize import naturaltime from django.core.cache import cache -from django.core.exceptions import ValidationError +from django.core.exceptions import SuspiciousFileOperation, ValidationError from django.core.files.base import ContentFile from django.core.files.storage import default_storage +from django.core.files.utils import validate_file_name from django.core.mail import EmailMultiAlternatives, get_connection from django.core.mail.utils import DNS_NAME from django.core.validators import MinLengthValidator, MinValueValidator @@ -45,6 +48,7 @@ from django_q.signals import post_spawn from djmoney.contrib.exchange.exceptions import MissingRate 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 @@ -85,8 +89,8 @@ class RenderMeta(enums.ChoicesType): return [] -class RenderChoices(models.TextChoices, metaclass=RenderMeta): # type: ignore - """Class for creating enumerated string choices for schema rendering.""" +class RenderChoices(models.TextChoices, metaclass=RenderMeta): + """Class for creating enumerated string choices for schema rendering.""" # ty:ignore[conflicting-metaclass] class MetaMixin(models.Model): @@ -246,11 +250,14 @@ class BaseInvenTreeSetting(models.Model): if len(missing_keys) > 0: logger.info('Building %s default values for %s', len(missing_keys), cls) - cls.objects.bulk_create([ - cls(key=key, value=cls.get_setting_default(key), **kwargs) - for key in missing_keys - if not key.startswith('_') - ]) + cls.objects.bulk_create( + [ + cls(key=key, value=cls.get_setting_default(key), **kwargs) + for key in missing_keys + if not key.startswith('_') + ], + batch_size=250, + ) except Exception as exc: logger.exception( 'Failed to build default values for %s (%s)', cls, type(exc) @@ -363,9 +370,15 @@ class BaseInvenTreeSetting(models.Model): # Specify any "default" values which are not in the database settings_definition = settings_definition or cls.SETTINGS + + all_settings = OrderedDict() + for key, setting in settings_definition.items(): - if key.upper() not in settings: - settings[key.upper()] = cls( + # If the setting is already in the database, use that value + if key.upper() in settings: + all_settings[key] = settings[key.upper()] + else: + all_settings[key.upper()] = cls( key=key.upper(), value=cls.get_setting_default(key, **filters), **filters, @@ -373,10 +386,10 @@ class BaseInvenTreeSetting(models.Model): # remove any hidden settings if exclude_hidden and setting.get('hidden', False): - del settings[key.upper()] + del all_settings[key.upper()] # format settings values and remove protected - for key, setting in settings.items(): + for key, setting in all_settings.items(): validator = cls.get_setting_validator(key, **filters) if cls.is_protected(key, **filters) and setting.value != '': @@ -389,7 +402,7 @@ class BaseInvenTreeSetting(models.Model): except ValueError: setting.value = cls.get_setting_default(key, **filters) - return settings + return all_settings @classmethod def allValues( @@ -1084,7 +1097,7 @@ class BaseInvenTreeSetting(models.Model): return self.__class__.validator_is_bool(validator) - def as_bool(self): + def as_bool(self) -> bool: """Return the value of this setting converted to a boolean value. Warning: Only use on values where is_bool evaluates to true! @@ -1920,6 +1933,8 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel model_id: The ID of the model to which this attachment is linked attachment: The uploaded file url: An external URL + thumbnail: A generated thumbnail for the uploaded file (if applicable) + is_image: True if this attachment is a valid image file comment: A comment or description for the attachment user: The user who uploaded the attachment upload_date: The date the attachment was uploaded @@ -1928,6 +1943,8 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel tags: Tags for the attachment """ + THUMBNAIL_SIZE = 256 + class Meta: """Metaclass options.""" @@ -1938,6 +1955,31 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel choice_fnc = common.validators.attachment_model_options + def delete(self, *args, **kwargs): + """Custom delete method for the Attachment model. + + - Ensure that the attached file is deleted from storage when the database entry is removed + """ + attachment = self.attachment + thumbnail = self.thumbnail + + super().delete(*args, **kwargs) + + # Delete the associated files from storage (if they exist)W + if attachment and default_storage.exists(attachment.name): + try: + # Remove the attached file from storage + default_storage.delete(attachment.name) + except Exception: # pragma: no cover + pass + + if thumbnail and default_storage.exists(thumbnail.name): + try: + # Remove the thumbnail file from storage + default_storage.delete(thumbnail.name) + except Exception: # pragma: no cover + pass + def save(self, *args, **kwargs): """Custom 'save' method for the Attachment model. @@ -1945,6 +1987,10 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel - Ensure that the 'content_type' and 'object_id' fields are set - Run extra validations """ + import common.tasks + + rebuild = kwargs.pop('rebuild', True) + # Either 'attachment' or 'link' must be specified! if not self.attachment and not self.link: raise ValidationError({ @@ -1972,6 +2018,12 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel if self.file_size != 0: super().save() + # Offload a background task to update the thumbnail for this attachment + if rebuild: + InvenTree.tasks.offload_task( + common.tasks.rebuild_attachment, self.pk, group='attachments' + ) + def clean_svg(self, field): """Sanitize SVG file before saving.""" cleaned = sanitize_svg(field.file.read()) @@ -1983,6 +2035,60 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel return os.path.basename(self.attachment.name) return str(self.link) + def validate_rename(self, filename: str): + """Validate that the provided filename is valid, for renaming an attachment.""" + filename = filename.strip() + + if not self.attachment: + raise ValidationError(_('No file attached to rename')) + + if not filename: + raise ValidationError(_('Filename cannot be empty')) + + try: + validate_file_name(filename, allow_relative_path=False) + except SuspiciousFileOperation: + raise ValidationError(_('Invalid filename')) + + current_ext = os.path.splitext(self.attachment.name)[1] + new_ext = os.path.splitext(filename)[1] + + if current_ext.lower() != new_ext.lower(): + raise ValidationError(_('Cannot change file extension')) + + def rename(self, filename: str): + """Rename the attached file.""" + self.validate_rename(filename) + + old_path = Path(self.attachment.name) + new_path = old_path.parent / filename + + if old_path == new_path: # pragma: no cover + # No change in filename + return + + if not new_path.is_relative_to(old_path.parent): # pragma: no cover + raise ValidationError(_('Invalid filename')) + + new_path = new_path.as_posix() + + if default_storage.exists(new_path): + raise ValidationError(_('A file with this name already exists')) + + # Create a new file with the new name, and delete the old file + new_path = default_storage.save(new_path, self.attachment.file) + + # Ensure that the new file exists + if not default_storage.exists(new_path): # pragma: no cover + raise ValidationError(_('Failed to save renamed file')) + + # Update the database file path + self.attachment.name = new_path + self.save() + + # Remove the old path + default_storage.delete(old_path) + model_type = models.CharField( max_length=100, validators=[common.validators.validate_attachment_model_type], @@ -1995,11 +2101,19 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel attachment = models.FileField( upload_to=rename_attachment, verbose_name=_('Attachment'), + validators=[common.validators.validate_attachment_file], help_text=_('Select file to attach'), blank=True, null=True, ) + thumbnail = models.ImageField( + verbose_name=_('Thumbnail'), + help_text=_('Thumbnail image for this attachment'), + blank=True, + null=True, + ) + link = InvenTree.fields.InvenTreeURLField( blank=True, null=True, @@ -2032,6 +2146,12 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel help_text=_('Date the file was uploaded'), ) + is_image = models.BooleanField( + default=False, + verbose_name=_('Is image'), + help_text=_('True if this attachment is a valid image file'), + ) + file_size = models.PositiveIntegerField( default=0, verbose_name=_('File size'), help_text=_('File size in bytes') ) @@ -2075,6 +2195,69 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel return model_class.check_related_permission(permission, user) + def check_is_image(self) -> bool: + """Check if the attached file is an image. + + We consider it a valid image if: + + - The file exists in storage + - The file can be opened and verified by the PIL library + + """ + if not self.attachment: + return False + + if not self.attachment.name: + return False + + try: + if not default_storage.exists(self.attachment.name): + return False + except Exception: + return False + + img_data = default_storage.open(self.attachment.name).read() + + try: + Image.open(BytesIO(img_data)).verify() + return True + except Exception: + return False + + def generate_thumbnail(self): + """Generate a thumbnail for the attached image.""" + # Remove any existing thumbnail + if self.thumbnail: + self.thumbnail.delete(save=False) + + if not self.attachment: + return + + if not self.attachment.name or not default_storage.exists(self.attachment.name): + return + + # TODO: Offload to plugins, for creating custom thumbnails for different file types + # TODO: If a plugin provides a thumbnail, return early + + # Default action is to generate a thumbnail for image files + try: + img_data = default_storage.open(self.attachment.name).read() + except Exception: + # No file found, or file cannot be read - cannot generate thumbnail + return + + try: + img = Image.open(BytesIO(img_data)) + img.thumbnail((self.THUMBNAIL_SIZE, self.THUMBNAIL_SIZE)) + thumb_io = BytesIO() + img.save(thumb_io, format='PNG') + thumb_io.seek(0) + + thumb_name = f'thumb_{os.path.basename(self.attachment.name)}' + self.thumbnail.save(thumb_name, ContentFile(thumb_io.read()), save=False) + except Exception: + pass + class InvenTreeCustomUserStateModel(models.Model): """Custom model to extends any registered state with extra custom, user defined states. @@ -2313,11 +2496,39 @@ class SelectionList(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeMo """Return the API URL associated with the SelectionList model.""" return reverse('api-selectionlist-list') - def get_choices(self): - """Return the choices for the selection list.""" - choices = self.entries.filter(active=True) + def get_choices(self, active: Optional[bool] = True): + """Return the choices for the selection list. + + Arguments: + active: If specified, filter choices by active status + + Returns: + List of choice values for this selection list + """ + choices = self.entries.all() + + if active is not None: + choices = choices.filter(active=active) + return [c.value for c in choices] + def has_choice(self, value: str, active: Optional[bool] = None): + """Check if the selection list has a particular choice. + + Arguments: + value: The value to check for + active: If specified, filter choices by active status + + Returns: + True if the choice exists in the selection list, False otherwise + """ + choices = self.entries.all() + + if active is not None: + choices = choices.filter(active=active) + + return choices.filter(value=value).exists() + class SelectionListEntry(models.Model): """Class which represents a single entry in a SelectionList. @@ -2574,7 +2785,7 @@ def post_save_parameter_template(sender, instance, created, **kwargs): common.tasks.rebuild_parameters, instance.pk, force_async=True, - group='part', + group='parameters', ) diff --git a/src/backend/InvenTree/common/serializers.py b/src/backend/InvenTree/common/serializers.py index ae4278a3d1..c8e2f13920 100644 --- a/src/backend/InvenTree/common/serializers.py +++ b/src/backend/InvenTree/common/serializers.py @@ -1,4 +1,4 @@ -"""JSON serializers for common components.""" +"""API serializers for common components.""" from django.contrib.contenttypes.models import ContentType from django.db.models import Count, OuterRef, Subquery @@ -28,7 +28,7 @@ from InvenTree.serializers import ( InvenTreeAttachmentSerializerField, InvenTreeImageSerializerField, InvenTreeModelSerializer, - enable_filter, + OptionalField, ) from plugin import registry as plugin_registry from users.serializers import OwnerSerializer, UserSerializer @@ -42,7 +42,7 @@ class SettingsValueField(serializers.Field): """Return the object instance, not the attribute value.""" return instance - def to_representation(self, instance: common_models.InvenTreeSetting) -> str: + def to_representation(self, instance: common_models.InvenTreeSetting): """Return the value of the setting. Protected settings are returned as '***' @@ -381,7 +381,16 @@ class ConfigSerializer(serializers.Serializer): """Return the configuration data as a dictionary.""" if not isinstance(instance, str): instance = list(instance.keys())[0] - return {'key': instance, **self.instance[instance]} + + data = {'key': instance} + + for k, v in self.instance.get(instance, {}).items(): + if k == 'default_value': + # Skip sensitive default values + continue + data[k] = v + + return data class NotesImageSerializer(InvenTreeModelSerializer): @@ -457,7 +466,7 @@ class FlagSerializer(serializers.Serializer): data = {'key': instance, 'state': flag_state(instance, request=request)} if request and request.user.is_superuser: - data['conditions'] = self.instance[instance] + data['conditions'] = self.instance.get(instance) return data @@ -522,6 +531,78 @@ class ErrorMessageSerializer(InvenTreeModelSerializer): read_only_fields = ['when', 'info', 'data', 'path', 'pk'] +class TaskDetailSerializer(serializers.Serializer): + """Serializer for a background task detail.""" + + task_id = serializers.CharField(read_only=True) + exists = serializers.BooleanField(read_only=True) + pending = serializers.BooleanField(read_only=True) + complete = serializers.BooleanField(read_only=True) + success = serializers.BooleanField(read_only=True) + http_status = serializers.IntegerField(read_only=True) + + @classmethod + def from_task(cls, task_id: str | bool | None) -> 'TaskDetailSerializer': + """Create a TaskDetailSerializer instance from a django_q Task. + + Arguments: + task_id: The ID of the task to retrieve details for. + + Returns: + An instance of TaskDetailSerializer with the task details. + + Notes: + - If the provided task_id is None, the task has not been run, or has errored out + - If the provided task_id is a boolean, the task has been run synchronously, and the boolean value indicates success or failure + - If the provided task_id is a string, the task has been offloaded to the background worker, and the details can be from the database + + """ + from InvenTree.tasks import get_queued_task + + if task_id is None or type(task_id) is bool: + # If the task_id is a boolean, the task has been run synchronously + return cls({ + 'task_id': '', + 'exists': False, + 'pending': False, + 'complete': task_id is not None, + 'success': False if task_id is None else bool(task_id), + 'http_status': 404 if task_id is None else 200, + }) + + # A non-boolean result indicates that the task has been offloaded to the background worker + success = django_q.models.Success.objects.filter(id=task_id).first() + failure = django_q.models.Failure.objects.filter(id=task_id).first() + task = ( + success + or failure + or django_q.models.Task.objects.filter(id=task_id).first() + ) + queued = False + + exists = bool(success or failure or task) + + if not exists: + # If the task has not been started yet, it may be present in the queue + queued = bool(get_queued_task(task_id)) + + complete = bool(success) or bool(failure) + + # Determine the http_status code for the task + # - 200: Task exists and has been completed + # - 404: Task does not exist + http_status = 200 if exists or queued else 404 + + return cls({ + 'task_id': task_id, + 'exists': exists or queued, + 'pending': queued, + 'complete': complete, + 'success': bool(success), + 'http_status': http_status, + }) + + class TaskOverviewSerializer(serializers.Serializer): """Serializer for background task overview.""" @@ -649,9 +730,11 @@ class AttachmentSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): fields = [ 'pk', 'attachment', + 'thumbnail', 'filename', 'link', 'comment', + 'is_image', 'upload_date', 'upload_user', 'user_detail', @@ -661,7 +744,14 @@ class AttachmentSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): 'tags', ] - read_only_fields = ['pk', 'file_size', 'upload_date', 'upload_user', 'filename'] + read_only_fields = [ + 'pk', + 'file_size', + 'upload_date', + 'upload_user', + 'filename', + 'is_image', + ] def __init__(self, *args, **kwargs): """Override the model_type field to provide dynamic choices.""" @@ -678,6 +768,8 @@ class AttachmentSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): attachment = InvenTreeAttachmentSerializerField(required=False, allow_null=True) + thumbnail = InvenTreeImageSerializerField(read_only=True, allow_null=True) + # The 'filename' field must be present in the serializer filename = serializers.CharField( label=_('Filename'), required=False, source='basename', allow_blank=False @@ -785,6 +877,7 @@ class ParameterSerializer( 'note', 'updated', 'updated_by', + # Optional fields 'template_detail', 'updated_by_detail', ] @@ -834,17 +927,22 @@ class ParameterSerializer( allow_null=False, ) - updated_by_detail = enable_filter( - UserSerializer( - source='updated_by', read_only=True, allow_null=True, many=False - ), - True, + updated_by_detail = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={ + 'source': 'updated_by', + 'read_only': True, + 'allow_null': True, + 'many': False, + }, + default_include=True, prefetch_fields=['updated_by'], ) - template_detail = enable_filter( - ParameterTemplateSerializer(source='template', read_only=True, many=False), - True, + template_detail = OptionalField( + serializer_class=ParameterTemplateSerializer, + serializer_kwargs={'source': 'template', 'read_only': True, 'many': False}, + default_include=True, prefetch_fields=['template', 'template__model_type'], ) @@ -908,7 +1006,7 @@ class SelectionListSerializer(InvenTreeModelSerializer): 'entry_count', ] - default = SelectionEntrySerializer(read_only=True, many=False) + 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) diff --git a/src/backend/InvenTree/common/setting/system.py b/src/backend/InvenTree/common/setting/system.py index 156e6e61b3..c646aa843d 100644 --- a/src/backend/InvenTree/common/setting/system.py +++ b/src/backend/InvenTree/common/setting/system.py @@ -49,7 +49,8 @@ def validate_part_name_format(value): }) # Attempt to render the template with a dummy Part instance - p = Part(name='test part', description='some test part') + # Use pk=1 to ensure conditional checks like {% if part.pk %} are evaluated + p = Part(pk=1, name='test part', description='some test part') try: SandboxedEnvironment().from_string(value).render({'part': p}) @@ -234,6 +235,18 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'validator': bool, 'default': False, }, + 'INVENTREE_SHOW_SUPERUSER_BANNER': { + 'name': _('Show superuser banner'), + 'description': _('Show a warning banner in the UI when logged in as superuser'), + 'validator': bool, + 'default': True, + }, + 'INVENTREE_SHOW_ADMIN_BANNER': { + 'name': _('Show admin banner'), + 'description': _('Show a warning banner in the UI when logged in as admin'), + 'validator': bool, + 'default': False, + }, 'INVENTREE_COMPANY_NAME': { 'name': _('Company name'), 'description': _('Internal company name'), @@ -273,25 +286,12 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'choices': common.currency.currency_exchange_plugins, 'default': 'inventreecurrencyexchange', }, - 'INVENTREE_DOWNLOAD_FROM_URL': { - 'name': _('Download from URL'), - 'description': _('Allow download of remote images and files from external URL'), - 'validator': bool, - 'default': False, - }, - 'INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE': { - 'name': _('Download Size Limit'), - 'description': _('Maximum allowable download size for remote image'), + 'INVENTREE_UPLOAD_MAX_SIZE': { + 'name': _('Upload Size Limit'), + 'description': _('Maximum allowable upload size for images and files'), 'units': 'MB', - 'default': 1, - 'validator': [int, MinValueValidator(1), MaxValueValidator(25)], - }, - 'INVENTREE_DOWNLOAD_FROM_URL_USER_AGENT': { - 'name': _('User-agent used to download from URL'), - 'description': _( - 'Allow to override the user-agent used to download images and files from external URL (leave blank for the default)' - ), - 'default': '', + 'default': 10, + 'validator': [int, MinValueValidator(1)], }, 'INVENTREE_STRICT_URLS': { 'name': _('Strict URL Validation'), @@ -402,6 +402,12 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'choices': barcode_plugins, 'default': 'inventreebarcode', }, + 'PART_ENABLE_LOCKING': { + 'name': _('Part Locking'), + 'description': _('Enable locking of parts to prevent modification'), + 'validator': bool, + 'default': True, + }, 'PART_ENABLE_REVISION': { 'name': _('Part Revisions'), 'description': _('Enable revision field for Part'), @@ -637,6 +643,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'PART_BOM_ALLOW_ZERO_QUANTITY': { + 'name': _('Allow BOM Zero Quantity'), + 'description': _( + 'Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity' + ), + 'default': False, + 'validator': bool, + }, 'LABEL_ENABLE': { 'name': _('Enable label printing'), 'description': _('Enable label printing from the web interface'), @@ -695,6 +709,18 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': True, 'validator': bool, }, + 'STOCK_ALLOW_EDIT_SERIAL': { + 'name': _('Allow Edit Serial Number'), + 'description': _('Allow editing of serial number for stock items'), + 'default': True, + 'validator': bool, + }, + 'STOCK_ALLOW_DELETE_SERIALIZED': { + 'name': _('Delete Serialized Stock'), + 'description': _('Allow deletion of stock items which have a serial number'), + 'default': True, + 'validator': bool, + }, 'STOCK_BATCH_CODE_TEMPLATE': { 'name': _('Batch Code Template'), 'description': _('Template for generating default batch codes for stock items'), @@ -805,6 +831,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'BUILDORDER_EXTERNAL_REQUIRED': { + 'name': _('Require External Build Orders'), + 'description': _( + 'Require an external build order when ordering assembled parts from an external supplier' + ), + 'default': False, + 'validator': bool, + }, 'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS': { 'name': _('Block Until Tests Pass'), 'description': _( @@ -883,6 +917,34 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'TRANSFERORDER_ENABLED': { + 'name': _('Enable Transfer Orders'), + 'description': _('Enable transfer order functionality in the user interface'), + 'validator': bool, + 'default': False, + }, + 'TRANSFERORDER_REFERENCE_PATTERN': { + 'name': _('Transfer Order Reference Pattern'), + 'description': _( + 'Required pattern for generating Transfer Order reference field' + ), + 'default': 'TO-{ref:04d}', + 'validator': order.validators.validate_transfer_order_reference_pattern, + }, + 'TRANSFERORDER_REQUIRE_RESPONSIBLE': { + 'name': _('Require Responsible Owner'), + 'description': _('A responsible owner must be assigned to each order'), + 'default': False, + 'validator': bool, + }, + 'SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS': { + 'name': _('Block Incomplete Item Tests'), + 'description': _( + 'Prevent allocation of stock items to sales orders if required item tests are incomplete' + ), + 'default': False, + 'validator': bool, + }, 'PURCHASEORDER_REFERENCE_PATTERN': { 'name': _('Purchase Order Reference Pattern'), 'description': _( @@ -1167,6 +1229,20 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': True, 'validator': bool, }, + 'WEEK_STARTS_ON': { + 'name': _('Week Starts On'), + 'description': _('Starting day of the week, for display in calendar views'), + 'default': '1', + 'choices': [ + ('0', _('Sunday')), + ('1', _('Monday')), + ('2', _('Tuesday')), + ('3', _('Wednesday')), + ('4', _('Thursday')), + ('5', _('Friday')), + ('6', _('Saturday')), + ], + }, '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 1971533663..0e788c017f 100644 --- a/src/backend/InvenTree/common/setting/type.py +++ b/src/backend/InvenTree/common/setting/type.py @@ -26,6 +26,7 @@ class SettingsKeyType(TypedDict, total=False): validator: Validation function/list of functions for the setting (optional, default: None, e.g: bool, int, str, MinValueValidator, ...) default: Default value or function that returns default value (optional) choices: Function that returns or value of list[tuple[str: key, str: display value]] (optional) + model_filters: Filters to apply when querying the associated model (optional) hidden: Hide this setting from settings page (optional) before_save: Function that gets called after save with *args, **kwargs (optional) after_save: Function that gets called after save with *args, **kwargs (optional) @@ -42,6 +43,7 @@ class SettingsKeyType(TypedDict, total=False): validator: Callable | list[Callable] | tuple[Callable] default: Callable | Any choices: list[tuple[str, str]] | Callable[[], list[tuple[str, str]]] + model_filters: dict[str, Any] hidden: bool before_save: Callable[..., None] after_save: Callable[..., None] diff --git a/src/backend/InvenTree/common/setting/user.py b/src/backend/InvenTree/common/setting/user.py index 23dee7e5bd..c9cae610ba 100644 --- a/src/backend/InvenTree/common/setting/user.py +++ b/src/backend/InvenTree/common/setting/user.py @@ -251,6 +251,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'SHOW_BOM_SUBASSEMBLY_LEVELS': { + 'name': _('Show Subassemblies in BOM table'), + 'description': _('Enable display of subassemblies in the BOM table'), + 'default': True, + 'validator': bool, + }, 'NOTIFICATION_ERROR_REPORT': { 'name': _('Receive error reports'), 'description': _('Receive notifications for system errors'), @@ -262,4 +268,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'description': _('Save the last used printing machines for a user'), 'default': '', }, + 'DISPLAY_ITEMS_FINAL_LEVEL': { + 'name': _('Display Items at Final Level'), + 'description': _( + 'Automatically default to showing items/parts instead of sub-levels for locations or categories with no children' + ), + 'default': False, + 'validator': bool, + }, } diff --git a/src/backend/InvenTree/common/settings.py b/src/backend/InvenTree/common/settings.py index 79cda8ca50..0e32fb99a5 100644 --- a/src/backend/InvenTree/common/settings.py +++ b/src/backend/InvenTree/common/settings.py @@ -28,6 +28,7 @@ def global_setting_overrides() -> dict: def get_global_setting(key, backup_value=None, environment_key=None, **kwargs): """Return the value of a global setting using the provided key.""" + import InvenTree.ready from common.models import InvenTreeSetting if environment_key: @@ -38,6 +39,10 @@ def get_global_setting(key, backup_value=None, environment_key=None, **kwargs): if backup_value is not None: kwargs['backup_value'] = backup_value + # Prevent database writes if we are in a read-only command + if InvenTree.ready.isReadOnlyCommand(): + kwargs['create'] = False + return InvenTreeSetting.get_setting(key, **kwargs) @@ -53,6 +58,12 @@ def set_global_setting(key, value, change_user=None, create=True, **kwargs): kwargs['change_user'] = change_user kwargs['create'] = create + if get_global_setting(key, create=False, cache=False) == value: + logger.debug( + f'Global setting "{key}" already has the desired value, no update needed' + ) + return True + return InvenTreeSetting.set_setting(key, value, **kwargs) @@ -70,11 +81,11 @@ def set_global_warning(key: str, options: Optional[dict] = None) -> bool: key (str): The key for the warning. options (dict or bool): Options for the warning, or True to set a default warning. - Raises: - ValueError: If the key is not provided. - Returns: bool: True if the warning was checked / set successfully, False if no check was performed. + + Raises: + ValueError: If the key is not provided. """ if not key: raise ValueError('Key must be provided for global warning setting.') diff --git a/src/backend/InvenTree/common/tasks.py b/src/backend/InvenTree/common/tasks.py index 6a86367937..43afef5245 100644 --- a/src/backend/InvenTree/common/tasks.py +++ b/src/backend/InvenTree/common/tasks.py @@ -204,3 +204,21 @@ def rebuild_parameters(template_id): if n > 0: logger.info("Rebuilt %s parameters for template '%s'", n, template.name) + + +@tracer.start_as_current_span('rebuild_attachment') +def rebuild_attachment(attachment_id: int): + """Rebuild the given attachment, if possible. + + This task is called whenever an attachment is saved, and perform the following tasks: + + - Check if the attachment is an image file, and update the "is_image" field accordingly + - Attempt to generate a thumbnail for the attachment + """ + from common.models import Attachment + + attachment = Attachment.objects.get(pk=attachment_id) + + attachment.is_image = attachment.check_is_image() + attachment.generate_thumbnail() + attachment.save(rebuild=False) diff --git a/src/backend/InvenTree/common/test_api.py b/src/backend/InvenTree/common/test_api.py index aba7e70afe..d4875c9014 100644 --- a/src/backend/InvenTree/common/test_api.py +++ b/src/backend/InvenTree/common/test_api.py @@ -1,11 +1,56 @@ """API unit tests for InvenTree common functionality.""" +import io + +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage +from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse +from PIL import Image + import common.models from InvenTree.unit_test import InvenTreeAPITestCase +class DataOutputAPITests(InvenTreeAPITestCase): + """API tests for the DataOutput endpoint.""" + + roles = 'all' + + def setUp(self): + """Set up some test data for DataOutput API testing.""" + from report.models import DataOutput + + super().setUp() + + for ii in range(5): + DataOutput.objects.create( + output_type='test_output', + user=self.user if ii % 2 == 0 else None, + complete=ii % 2 == 1, + ) + + def test_data_output_list(self): + """Test the DataOutput API list endpoint.""" + url = reverse('api-data-output-list') + + # Non-staff user should only see outputs which are either enabled for all users, or created by themselves + self.user.is_staff = False + self.user.save() + response = self.get(url) + self.assertEqual(len(response.data), 3) + + for output in response.data: + self.assertEqual(output['user'], self.user.pk) + + # Set staff access = True, so we should see all outputs + self.user.is_staff = True + self.user.save() + response = self.get(url) + self.assertEqual(len(response.data), 5) + + class ParameterAPITests(InvenTreeAPITestCase): """Tests for the Parameter API.""" @@ -637,3 +682,320 @@ class ParameterAPITests(InvenTreeAPITestCase): self.assertFalse( common.models.Parameter.objects.filter(template=template.pk).exists() ) + + +class AttachmentAPITests(InvenTreeAPITestCase): + """Tests for the Attachment API.""" + + def test_attachments(self): + """Test API functionality for attachments.""" + from common.models import Attachment + from part.models import Part + + self.assignRole('part.add') + + part = Part.objects.create(name='Test Part', description='A part for testing') + + N = Attachment.objects.count() + + # Upload multiple attachments against the part instance + for ii in range(5): + file_object = io.StringIO('Hello world') + file_object.seek(0) + + fn = f'test_file_{ii}.txt' + + content_file = ContentFile(file_object.read(), name=fn) + + url = reverse('api-attachment-list') + + response = self.post( + url, + data={ + 'model_type': 'part', + 'model_id': part.pk, + 'attachment': content_file, + 'comment': f'This is test file {ii}', + }, + format='multipart', + expected_code=201, + ) + + data = response.data + + # Check that the file has actually been created + self.assertEqual(data['filename'], fn) + self.assertTrue( + default_storage.exists(data['attachment'].replace('/media/', '')) + ) + + # Check that we have the expected number of attachments + self.assertEqual(Attachment.objects.count(), N + 5) + self.assertEqual(part.attachments.count(), 5) + + # Let's rename one of the attachments + att = part.attachments.first() + self.assertEqual(att.basename, 'test_file_0.txt') + + url = reverse('api-attachment-detail', kwargs={'pk': att.pk}) + + # A few failed attempts + for new_name in [ + 'different_ext.docx', + 'test_file_1.txt', + '../../test_file.txt', + ]: + print('- ATTEMPTING:', new_name) + response = self.patch(url, data={'filename': new_name}, expected_code=400) + + att.refresh_from_db() + self.assertEqual(att.basename, 'test_file_0.txt') + + # Let's try seriously this time + new_name = 'a_new_file.txt' + response = self.patch(url, data={'filename': new_name}, expected_code=200) + + att.refresh_from_db() + self.assertEqual(att.basename, new_name) + + # Check that the file has been renamed on disk + self.assertTrue( + default_storage.exists(f'attachments/part/{part.pk}/{new_name}') + ) + self.assertFalse( + default_storage.exists(f'attachments/part/{part.pk}/test_file_0.txt') + ) + + # Next, let's delete the attachment manually - via the API + response = self.delete(url, expected_code=403) + self.assignRole('part.delete') + response = self.delete(url, expected_code=204) + + # Check that the file has been deleted from disk + self.assertFalse( + default_storage.exists(f'attachments/part/{part.pk}/{new_name}') + ) + + self.assertEqual(Attachment.objects.count(), N + 4) + self.assertEqual(part.attachments.count(), 4) + + # Fetch the remaining attachments + attachments = list(part.attachments.all()) + + # Now, delete the part instance + part.active = False + part.save() + part.delete() + + self.assertEqual(Attachment.objects.count(), N) + + for att in attachments: + # Ensure that the file associated with each attachment has been removed + self.assertFalse(default_storage.exists(att.attachment.path)) + + +class AttachmentThumbnailAPITests(InvenTreeAPITestCase): + """Tests for thumbnail generation when uploading attachments via the API.""" + + def setUp(self): + """Set up a Part instance and required roles.""" + from part.models import Part + + super().setUp() + self.assignRole('part.add') + self.assignRole('part.delete') + self.part = Part.objects.create( + name='Thumbnail Test Part', description='Part for thumbnail testing' + ) + + def _make_image_file(self, name='test.png', size=(100, 100), color='red'): + """Return a SimpleUploadedFile containing a valid PNG image.""" + buf = io.BytesIO() + Image.new('RGB', size, color=color).save(buf, format='PNG') + return SimpleUploadedFile(name, buf.getvalue(), content_type='image/png') + + def _upload_attachment(self, file_obj, expected_code=201): + """Upload a file attachment against the test part and return the response.""" + return self.post( + reverse('api-attachment-list'), + data={ + 'model_type': 'part', + 'model_id': self.part.pk, + 'attachment': file_obj, + }, + format='multipart', + expected_code=expected_code, + ) + + def test_thumbnail_valid_image(self): + """Uploading a valid image file should set is_image=True and generate a thumbnail.""" + from common.models import Attachment + + response = self._upload_attachment(self._make_image_file()) + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertTrue(att.is_image) + self.assertTrue(att.thumbnail) + self.assertTrue(default_storage.exists(att.thumbnail.name)) + + def test_thumbnail_invalid_image(self): + """Uploading a file with an image extension but invalid image data should not create a thumbnail.""" + from common.models import Attachment + + bad_file = SimpleUploadedFile( + 'corrupt.png', b'this is not image data', content_type='image/png' + ) + response = self._upload_attachment(bad_file) + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + def test_thumbnail_non_image_file(self): + """Uploading a non-image file should leave is_image=False with no thumbnail.""" + from common.models import Attachment + + txt_file = SimpleUploadedFile( + 'document.txt', b'Hello, InvenTree!', content_type='text/plain' + ) + response = self._upload_attachment(txt_file) + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + def test_thumbnail_large_image(self): + """A large image attachment should produce a thumbnail no larger than THUMBNAIL_SIZE on each side.""" + from common.models import Attachment + + response = self._upload_attachment(self._make_image_file(size=(1000, 1000))) + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertTrue(att.is_image) + self.assertTrue(att.thumbnail) + + thumb_data = default_storage.open(att.thumbnail.name).read() + thumb_img = Image.open(io.BytesIO(thumb_data)) + self.assertLessEqual(thumb_img.width, Attachment.THUMBNAIL_SIZE) + self.assertLessEqual(thumb_img.height, Attachment.THUMBNAIL_SIZE) + + def test_thumbnail_deleted_with_attachment(self): + """Deleting an attachment via the API should also remove its thumbnail from storage.""" + from common.models import Attachment + + response = self._upload_attachment(self._make_image_file()) + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertTrue(att.thumbnail) + thumb_name = att.thumbnail.name + att_name = att.attachment.name + + self.assertTrue(default_storage.exists(att_name)) + self.assertTrue(default_storage.exists(thumb_name)) + + self.delete( + reverse('api-attachment-detail', kwargs={'pk': att.pk}), expected_code=204 + ) + + self.assertFalse(default_storage.exists(att_name)) + self.assertFalse(default_storage.exists(thumb_name)) + + def test_thumbnail_zero_byte_file(self): + """Uploading a zero-byte file should be rejected by Django's file validation before reaching thumbnail logic.""" + empty_file = SimpleUploadedFile('empty.png', b'', content_type='image/png') + # Django's FileField rejects empty uploads at the serializer/validation layer + response = self._upload_attachment(empty_file, expected_code=400) + self.assertIn('attachment', response.data) + + def test_thumbnail_link_attachment(self): + """An attachment created with an external link (no file) should not generate a thumbnail.""" + from common.models import Attachment + + response = self.post( + reverse('api-attachment-list'), + data={ + 'model_type': 'part', + 'model_id': self.part.pk, + 'link': 'https://example.com/some/resource', + }, + format='multipart', + expected_code=201, + ) + + att = Attachment.objects.get(pk=response.data['pk']) + + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + def test_is_image_filter(self): + """The is_image filter on the attachment list endpoint should return only matching attachments.""" + url = reverse('api-attachment-list') + base_filters = {'model_type': 'part', 'model_id': self.part.pk} + + # Upload one valid image and three non-image attachments + self._upload_attachment(self._make_image_file('img1.png')) + self._upload_attachment( + SimpleUploadedFile( + 'corrupt.png', b'not image data', content_type='image/png' + ) + ) + self._upload_attachment( + SimpleUploadedFile('doc.txt', b'hello', content_type='text/plain') + ) + self.post( + url, + data={**base_filters, 'link': 'https://example.com/resource'}, + format='multipart', + expected_code=201, + ) + + all_attachments = self.get(url, base_filters, expected_code=200).data + self.assertEqual(len(all_attachments), 4) + + # is_image=true → only the valid image + images = self.get( + url, {**base_filters, 'is_image': 'true'}, expected_code=200 + ).data + self.assertEqual(len(images), 1) + self.assertTrue(images[0]['is_image']) + + # is_image=false → the three non-image attachments + non_images = self.get( + url, {**base_filters, 'is_image': 'false'}, expected_code=200 + ).data + self.assertEqual(len(non_images), 3) + self.assertTrue(all(not a['is_image'] for a in non_images)) + + def test_upload_exceeds_size_limit(self): + """Uploading a file that exceeds INVENTREE_UPLOAD_MAX_SIZE should be rejected with a 400 error.""" + from common.settings import get_global_setting, set_global_setting + + original_limit = get_global_setting('INVENTREE_UPLOAD_MAX_SIZE') + # Use a 1 MB ceiling so the test file stays small and fast + set_global_setting('INVENTREE_UPLOAD_MAX_SIZE', 1, change_user=None) + + limit_bytes = 1 * 1024 * 1024 + + try: + # File exactly at the limit — validator uses >, so this must be accepted + self._upload_attachment( + SimpleUploadedFile( + 'at_limit.txt', b'\x00' * limit_bytes, content_type='text/plain' + ), + expected_code=201, + ) + + # File one byte over the limit — must be rejected + response = self._upload_attachment( + SimpleUploadedFile( + 'over_limit.txt', + b'\x00' * (limit_bytes + 1), + content_type='text/plain', + ), + expected_code=400, + ) + self.assertIn('attachment', response.data) + finally: + set_global_setting( + 'INVENTREE_UPLOAD_MAX_SIZE', original_limit, change_user=None + ) diff --git a/src/backend/InvenTree/common/test_emails.py b/src/backend/InvenTree/common/test_emails.py index 355167d2c5..0ba8b24b9f 100644 --- a/src/backend/InvenTree/common/test_emails.py +++ b/src/backend/InvenTree/common/test_emails.py @@ -103,7 +103,9 @@ class EmailTests(InvenTreeAPITestCase): ) def test_email_api(self): """Test that the email api endpoints work.""" - self.post(reverse('api-email-test'), {'email': 'test@example.org'}) + self.post( + reverse('api-email-test'), {'email': 'test@example.org'}, expected_code=200 + ) response = self.get(reverse('api-email-list'), expected_code=200) self.assertIn('subject', response.data[0]) diff --git a/src/backend/InvenTree/common/test_migrations.py b/src/backend/InvenTree/common/test_migrations.py index 6c21dc1074..c6e62cefef 100644 --- a/src/backend/InvenTree/common/test_migrations.py +++ b/src/backend/InvenTree/common/test_migrations.py @@ -4,8 +4,10 @@ import io import os from django.core.files.base import ContentFile +from django.core.files.storage import default_storage from django_test_migrations.contrib.unittest_case import MigratorTestCase +from PIL import Image def get_legacy_models(): @@ -209,6 +211,85 @@ class TestForwardMigrations(MigratorTestCase): self.assertEqual(Attachment.objects.filter(model_type=model).count(), 2) +class TestAttachmentThumbnailMigration(MigratorTestCase): + """Test that migration 0043 correctly populates is_image and generates thumbnails for existing attachments.""" + + migrate_from = ('common', '0041_auto_20251203_1244') + migrate_to = ('common', '0043_auto_20260518_1206') + + def prepare(self): + """Create a set of attachments with different file types in the pre-migration state. + + At this point the Attachment model has no is_image or thumbnail fields yet. + Files are written to storage directly through the FileField so that the + data migration can find them at their stored paths. + """ + Attachment = self.old_state.apps.get_model('common', 'Attachment') + + # 1. Valid PNG image — migration should set is_image=True and create a thumbnail + buf = io.BytesIO() + Image.new('RGB', (100, 100), color='blue').save(buf, format='PNG') + Attachment.objects.create( + model_type='part', + model_id=1, + attachment=ContentFile(buf.getvalue(), name='valid_image.png'), + comment='valid_image', + ) + + # 2. File with a .png extension but non-image content — migration should leave is_image=False + Attachment.objects.create( + model_type='part', + model_id=1, + attachment=ContentFile(b'this is not image data', name='corrupt.png'), + comment='corrupt_image', + ) + + # 3. Plain text file — migration should leave is_image=False with no thumbnail + Attachment.objects.create( + model_type='part', + model_id=1, + attachment=ContentFile(b'Hello, InvenTree!', name='document.txt'), + comment='text_file', + ) + + # 4. Link attachment (no file at all) — migration should skip it entirely + Attachment.objects.create( + model_type='part', + model_id=1, + link='https://example.com/resource', + comment='link_attachment', + ) + + self.assertEqual(Attachment.objects.count(), 4) + + def test_attachment_thumbnails_after_migration(self): + """After applying migrations 0042 and 0043, verify is_image and thumbnail are correct.""" + Attachment = self.new_state.apps.get_model('common', 'Attachment') + + self.assertEqual(Attachment.objects.count(), 4) + + # Valid image → is_image set, thumbnail file created in storage + att = Attachment.objects.get(comment='valid_image') + self.assertTrue(att.is_image) + self.assertTrue(att.thumbnail) + self.assertTrue(default_storage.exists(att.thumbnail.name)) + + # Corrupt image → is_image not set, no thumbnail + att = Attachment.objects.get(comment='corrupt_image') + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + # Text file → is_image not set, no thumbnail + att = Attachment.objects.get(comment='text_file') + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + # Link attachment → is_image not set, no thumbnail + att = Attachment.objects.get(comment='link_attachment') + self.assertFalse(att.is_image) + self.assertFalse(att.thumbnail) + + def prep_currency_migration(self, vals: str): """Prepare the environment for the currency migration tests.""" # Set keys diff --git a/src/backend/InvenTree/common/tests.py b/src/backend/InvenTree/common/tests.py index 7df489209a..af0420e62d 100644 --- a/src/backend/InvenTree/common/tests.py +++ b/src/backend/InvenTree/common/tests.py @@ -86,6 +86,11 @@ class AttachmentTest(InvenTreeAPITestCase): } for fn, expected in filenames.items(): + expected_path = f'attachments/part/{part.pk}/{expected}' + # Remove the file if it already exists (i.e. from a previous test run) + if default_storage.exists(expected_path): + default_storage.delete(expected_path) + attachment = Attachment.objects.create( attachment=self.generate_file(fn), comment=f'Testing filename: {fn}', @@ -93,7 +98,6 @@ class AttachmentTest(InvenTreeAPITestCase): model_id=part.pk, ) - expected_path = f'attachments/part/{part.pk}/{expected}' self.assertEqual(attachment.attachment.name, expected_path) self.assertEqual(attachment.file_size, 15) @@ -1107,6 +1111,41 @@ class TaskListApiTests(InvenTreeAPITestCase): for task in response.data: self.assertEqual(task['name'], 'time.sleep') + def test_task_detail(self): + """Test the BackgroundTaskDetail API endpoint.""" + from InvenTree.tasks import offload_task + + # Force run a task + result = offload_task('fake_module.test_task', force_sync=True) + self.assertFalse(result) + self.assertEqual(type(result), bool) + + # Schedule a dummy task - and ensure it offloads to the worker + task_id = offload_task('fake_module.test_task', force_async=True) + self.assertIsNotNone(task_id) + self.assertEqual(type(task_id), str) + + url = reverse('api-task-detail', kwargs={'task_id': task_id}) + + data = self.get(url, expected_code=200).data + + self.assertEqual(data['task_id'], task_id) + self.assertTrue(data['exists']) + self.assertTrue(data['pending']) + self.assertFalse(data['complete']) + self.assertFalse(data['success']) + + # Perform a lookup for a non-existent task + url = reverse('api-task-detail', kwargs={'task_id': 'doesnotexist'}) + + data = self.get(url, expected_code=404).data + + self.assertEqual(data['task_id'], 'doesnotexist') + self.assertFalse(data['exists']) + self.assertFalse(data['pending']) + self.assertFalse(data['complete']) + self.assertFalse(data['success']) + class WebhookMessageTests(TestCase): """Tests for webhooks.""" @@ -1269,12 +1308,41 @@ class NotificationTest(InvenTreeAPITestCase): self.assertEqual( response.data['description'], - 'List view for all notifications of the current user.', + 'Notifications for the current user.\n\n- User can only view / delete their own notification objects', ) # POST action should fail (not allowed) response = self.post(url, {}, expected_code=405) + def test_api_read(self): + """Test that NotificationMessage can be marked as read.""" + # Create a notification message + NotificationMessage.objects.create( + user=self.user, + category='test', + message='This is a test notification', + target_object=self.user, + ) + user2 = get_user_model().objects.get(pk=2) + NotificationMessage.objects.create( + user=user2, + category='test', + message='This is a second test notification', + target_object=user2, + ) + + url = reverse('api-notifications-list') + self.assertEqual(NotificationMessage.objects.filter(read=True).count(), 0) + self.assertEqual(len(self.get(url, expected_code=200).data), 1) + + # Read with readall endpoint + self.post(reverse('api-notifications-readall'), {}, expected_code=200) + + self.assertEqual(NotificationMessage.objects.filter(read=True).count(), 1) + self.assertEqual(len(self.get(url, expected_code=200).data), 1) + # filtered by read status should be 0 + self.assertEqual(len(self.get(url, {'read': False}, expected_code=200).data), 0) + def test_bulk_delete(self): """Tests for bulk deletion of user notifications.""" from error_report.models import Error @@ -1317,12 +1385,18 @@ class NotificationTest(InvenTreeAPITestCase): # Now, let's bulk delete all 'unread' notifications via the API, # but only associated with the logged in user - response = self.delete(url, {'filters': {'read': False}}, expected_code=200) + read_notifications = NotificationMessage.objects.filter(read=True) + response = self.delete( + url, {'items': [ntf.pk for ntf in read_notifications]}, expected_code=200 + ) - # Only 7 notifications should have been deleted, + # Only 3 notifications should have been deleted, # as the notifications associated with other users must remain untouched - self.assertEqual(NotificationMessage.objects.count(), 13) - self.assertEqual(NotificationMessage.objects.filter(user=self.user).count(), 3) + self.assertEqual(NotificationMessage.objects.count(), 17) + self.assertEqual(NotificationMessage.objects.filter(user=self.user).count(), 7) + self.assertEqual( + NotificationMessage.objects.filter(user=self.user, read=True).count(), 0 + ) def test_simple(self): """Test that a simple notification can be created.""" @@ -1534,9 +1608,14 @@ class CurrencyAPITests(InvenTreeAPITestCase): # Updating via the external exchange may not work every time for _idx in range(5): - self.post( - reverse('api-currency-refresh'), expected_code=200, max_query_time=30 - ) + try: + self.post( + reverse('api-currency-refresh'), + expected_code=200, + max_query_time=30, + ) + except Exception: + continue # There should be some new exchange rate objects now if Rate.objects.all().exists(): @@ -1789,7 +1868,7 @@ class CustomUnitAPITest(InvenTreeAPITestCase): def test_api(self): """Test the CustomUnit API.""" - response = self.get(reverse('api-all-unit-list')) + response = self.get(reverse('api-custom-unit-all')) self.assertIn('default_system', response.data) self.assertIn('available_systems', response.data) self.assertIn('available_units', response.data) diff --git a/src/backend/InvenTree/common/validators.py b/src/backend/InvenTree/common/validators.py index 02c3805f96..226a42b7d2 100644 --- a/src/backend/InvenTree/common/validators.py +++ b/src/backend/InvenTree/common/validators.py @@ -2,7 +2,8 @@ import re -from django.core.exceptions import ValidationError +from django.core.exceptions import SuspiciousFileOperation, ValidationError +from django.core.files.storage import default_storage from django.utils.translation import gettext_lazy as _ import common.icons @@ -76,6 +77,21 @@ def validate_attachment_model_type(value): raise ValidationError('Model type does not support attachments') +def validate_attachment_file(attachment): + """Ensure that the provided attachment file is valid.""" + max_size = get_global_setting('INVENTREE_UPLOAD_MAX_SIZE', create=False) + + if attachment.size > (max_size * 1024 * 1024): + raise ValidationError( + _(f'File size exceeds maximum upload limit of {max_size} MB') + ) + + try: + default_storage.generate_filename(attachment.name) + except SuspiciousFileOperation: # pragma: no cover + raise ValidationError(_('Invalid file name')) + + def validate_notes_model_type(value): """Ensure that the provided model type is valid. diff --git a/src/backend/InvenTree/company/api.py b/src/backend/InvenTree/company/api.py index a3611566f7..e0639712a5 100644 --- a/src/backend/InvenTree/company/api.py +++ b/src/backend/InvenTree/company/api.py @@ -11,7 +11,7 @@ import part.models from data_exporter.mixins import DataExportViewMixin from InvenTree.api import ListCreateDestroyAPIView, ParameterListMixin from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration -from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS +from InvenTree.filters import SEARCH_ORDER_FILTER from InvenTree.mixins import ( ListCreateAPI, OutputOptionsMixin, @@ -179,11 +179,13 @@ class ManufacturerPartMixin(SerializerContextMixin): queryset = super().get_queryset(*args, **kwargs) queryset = queryset.prefetch_related('supplier_parts') + queryset = queryset.prefetch_related('part', 'part__pricing_data') return queryset class ManufacturerPartList( + DataExportViewMixin, ManufacturerPartMixin, SerializerContextMixin, OutputOptionsMixin, @@ -197,7 +199,7 @@ class ManufacturerPartList( """ filterset_class = ManufacturerPartFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = ManufacturerOutputOptions ordering_fields = ['part', 'IPN', 'MPN', 'manufacturer'] @@ -360,7 +362,7 @@ class SupplierPartList( """ filterset_class = SupplierPartFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = SupplierPartOutputOptions ordering_fields = [ @@ -475,7 +477,7 @@ class SupplierPriceBreakList( output_options = SupplierPriceBreakOutputOptions filterset_class = SupplierPriceBreakFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_fields = ['quantity', 'supplier', 'SKU', 'price'] search_fields = ['part__SKU', 'part__supplier__name'] diff --git a/src/backend/InvenTree/company/models.py b/src/backend/InvenTree/company/models.py index 90aeb23ae8..431f7ae11b 100644 --- a/src/backend/InvenTree/company/models.py +++ b/src/backend/InvenTree/company/models.py @@ -2,6 +2,7 @@ import os from decimal import Decimal +from typing import TypedDict from django.apps import apps from django.conf import settings @@ -53,7 +54,7 @@ def rename_company_image(instance, filename): return os.path.join(base, fn) -class CompanyReportContext(report.mixins.BaseReportContext): +class CompanyReportContext(report.mixins.BaseReportContext, TypedDict): """Report context for the Company model. Attributes: @@ -243,7 +244,11 @@ class Company( # We may have a pre-fetched primary address list if hasattr(self, 'primary_address_list'): addresses = self.primary_address_list - return addresses[0] if len(addresses) > 0 else None + return ( + addresses[0] + if len(addresses) > 0 and isinstance(addresses, list) + else None + ) # Otherwise, query the database return self.addresses.filter(primary=True).first() diff --git a/src/backend/InvenTree/company/serializers.py b/src/backend/InvenTree/company/serializers.py index eae59f1980..0ff71a39bc 100644 --- a/src/backend/InvenTree/company/serializers.py +++ b/src/backend/InvenTree/company/serializers.py @@ -1,8 +1,5 @@ """JSON serializers for Company app.""" -import io - -from django.core.files.base import ContentFile from django.db.models import Prefetch from django.utils.translation import gettext_lazy as _ @@ -17,7 +14,6 @@ from importer.registry import register_importer from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.ready import isGeneratingSchema from InvenTree.serializers import ( - FilterableCharField, FilterableSerializerMixin, InvenTreeCurrencySerializer, InvenTreeDecimalField, @@ -26,8 +22,7 @@ from InvenTree.serializers import ( InvenTreeMoneySerializer, InvenTreeTagModelSerializer, NotesFieldMixin, - RemoteImageMixin, - enable_filter, + OptionalField, ) from .models import ( @@ -114,7 +109,6 @@ class CompanySerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, NotesFieldMixin, - RemoteImageMixin, InvenTreeModelSerializer, ): """Serializer for Company object (full detail).""" @@ -146,7 +140,6 @@ class CompanySerializer( 'notes', 'parts_supplied', 'parts_manufactured', - 'remote_image', 'primary_address', 'tax_id', 'parameters', @@ -164,9 +157,10 @@ class CompanySerializer( return queryset - primary_address = enable_filter( - AddressBriefSerializer(read_only=True, allow_null=True), - False, + primary_address = OptionalField( + serializer_class=AddressBriefSerializer, + serializer_kwargs={'read_only': True, 'many': False, 'allow_null': True}, + default_include=False, filter_name='address_detail', prefetch_fields=[ Prefetch( @@ -193,27 +187,6 @@ class CompanySerializer( parameters = common.filters.enable_parameters_filter() - def save(self): - """Save the Company instance.""" - super().save() - - company = self.instance - - # Check if an image was downloaded from a remote URL - remote_img = getattr(self, 'remote_image_file', None) - - if remote_img and company: - fmt = remote_img.format or 'PNG' - buffer = io.BytesIO() - remote_img.save(buffer, format=fmt) - - # Construct a simplified name for the image - filename = f'company_{company.pk}_image.{fmt.lower()}' - - company.image.save(filename, ContentFile(buffer.getvalue())) - - return self.instance - @register_importer() class ContactSerializer(DataImportExportSerializerMixin, InvenTreeModelSerializer): @@ -263,27 +236,37 @@ class ManufacturerPartSerializer( parameters = common.filters.enable_parameters_filter() - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - source='part', many=False, read_only=True, allow_null=True - ), - True, - prefetch_fields=['part', 'part__pricing_data', 'part__category'], + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, + prefetch_fields=['part__category'], ) - pretty_name = enable_filter( - FilterableCharField(read_only=True, allow_null=True), filter_name='pretty' + pretty_name = OptionalField( + serializer_class=serializers.CharField, + serializer_kwargs={'read_only': True, 'allow_null': True}, + filter_name='pretty', ) manufacturer = serializers.PrimaryKeyRelatedField( queryset=Company.objects.filter(is_manufacturer=True) ) - manufacturer_detail = enable_filter( - CompanyBriefSerializer( - source='manufacturer', many=False, read_only=True, allow_null=True - ), - True, + manufacturer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'manufacturer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['manufacturer'], ) @@ -415,70 +398,86 @@ class SupplierPartSerializer( pack_quantity_native = serializers.FloatField(read_only=True) - price_breaks = enable_filter( - SupplierPriceBreakBriefSerializer( - source='pricebreaks', - many=True, - read_only=True, - allow_null=True, - label=_('Price Breaks'), - ), - False, + price_breaks = OptionalField( + serializer_class=SupplierPriceBreakBriefSerializer, + serializer_kwargs={ + 'source': 'pricebreaks', + 'many': True, + 'read_only': True, + 'allow_null': True, + 'label': _('Price Breaks'), + }, + default_include=False, filter_name='price_breaks', prefetch_fields=['pricebreaks'], ) parameters = common.filters.enable_parameters_filter() - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - label=_('Part'), source='part', many=False, read_only=True, allow_null=True - ), - False, + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'label': _('Part'), + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['part', 'part__pricing_data'], ) - supplier_detail = enable_filter( - CompanyBriefSerializer( - label=_('Supplier'), - source='supplier', - many=False, - read_only=True, - allow_null=True, - ), - False, + supplier_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'label': _('Supplier'), + 'source': 'supplier', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['supplier'], ) - manufacturer_detail = enable_filter( - CompanyBriefSerializer( - label=_('Manufacturer'), - source='manufacturer_part.manufacturer', - many=False, - read_only=True, - allow_null=True, - ), - False, + manufacturer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'label': _('Manufacturer'), + 'source': 'manufacturer_part.manufacturer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['manufacturer_part__manufacturer'], ) - pretty_name = enable_filter( - FilterableCharField(read_only=True, allow_null=True), filter_name='pretty' + pretty_name = OptionalField( + serializer_class=serializers.CharField, + serializer_kwargs={ + 'read_only': True, + 'allow_null': True, + 'label': _('Pretty Name'), + }, + default_include=False, + filter_name='pretty', ) supplier = serializers.PrimaryKeyRelatedField( label=_('Supplier'), queryset=Company.objects.filter(is_supplier=True) ) - manufacturer_part_detail = enable_filter( - ManufacturerPartSerializer( - label=_('Manufacturer Part'), - source='manufacturer_part', - part_detail=False, - read_only=True, - allow_null=True, - ), - False, + manufacturer_part_detail = OptionalField( + serializer_class=ManufacturerPartSerializer, + serializer_kwargs={ + 'label': _('Manufacturer Part'), + 'source': 'manufacturer_part', + 'part_detail': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['manufacturer_part'], ) @@ -568,18 +567,27 @@ class SupplierPriceBreakSerializer( return queryset - supplier_detail = enable_filter( - CompanyBriefSerializer( - source='part.supplier', many=False, read_only=True, allow_null=True - ), - False, + supplier_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'part.supplier', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['part__supplier'], ) - part_detail = enable_filter( - SupplierPartSerializer( - source='part', brief=True, many=False, read_only=True, allow_null=True - ), - False, + part_detail = OptionalField( + serializer_class=SupplierPartSerializer, + serializer_kwargs={ + 'source': 'part', + 'brief': True, + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['part', 'part__part', 'part__part__pricing_data'], ) diff --git a/src/backend/InvenTree/company/test_api.py b/src/backend/InvenTree/company/test_api.py index 6df854edd6..8570991643 100644 --- a/src/backend/InvenTree/company/test_api.py +++ b/src/backend/InvenTree/company/test_api.py @@ -507,6 +507,8 @@ class ManufacturerTest(InvenTreeAPITestCase): """Tests for the ManufacturerPart detail endpoint.""" mp = ManufacturerPart.objects.first() + self.assertIsNotNone(mp) + url = reverse('api-manufacturer-part-detail', kwargs={'pk': mp.pk}) response = self.get(url) diff --git a/src/backend/InvenTree/company/test_migrations.py b/src/backend/InvenTree/company/test_migrations.py index cfea9f7cca..741c7f187f 100644 --- a/src/backend/InvenTree/company/test_migrations.py +++ b/src/backend/InvenTree/company/test_migrations.py @@ -299,7 +299,7 @@ class TestAddressMigration(MigratorTestCase): c1 = Company.objects.filter(name='Company 1').first() c2 = Company.objects.filter(name='Company 2').first() - self.assertEqual(len(Address.objects.all()), 2) + self.assertEqual(Address.objects.count(), 2) a1 = Address.objects.filter(company=c1.pk).first() a2 = Address.objects.filter(company=c2.pk).first() diff --git a/src/backend/InvenTree/config_template.yaml b/src/backend/InvenTree/config_template.yaml index ab5f232127..4b790e7c17 100644 --- a/src/backend/InvenTree/config_template.yaml +++ b/src/backend/InvenTree/config_template.yaml @@ -18,15 +18,15 @@ # TO MAINTAINERS: Do not change database strings database: # --- Available options: --- - # ENGINE: Database engine. Selection from: + # engine: Database engine. Selection from: # - mysql # - postgresql # - sqlite3 - # NAME: Database name - # USER: Database username (if required) - # PASSWORD: Database password (if required) - # HOST: Database host address (if required) - # PORT: Database host port (if required) + # name: Database name + # user: Database username (if required) + # password: Database password (if required) + # host: Database host address (if required) + # port: Database host port (if required) # Base URL for the InvenTree server (or use the environment variable INVENTREE_SITE_URL) # site_url: 'http://localhost:8000' diff --git a/src/backend/InvenTree/generic/states/fields.py b/src/backend/InvenTree/generic/states/fields.py index 9ffa81d8eb..0ca677b4ab 100644 --- a/src/backend/InvenTree/generic/states/fields.py +++ b/src/backend/InvenTree/generic/states/fields.py @@ -194,7 +194,7 @@ class InvenTreeCustomStatusSerializerMixin: """Ensure the custom field is updated if the leader was changed.""" self.gather_custom_fields() # Mirror values from leader to follower - for field in self._custom_fields_leader: + for field in self._custom_fields_leader or []: follower_field_name = f'{field}_custom_key' if ( field in self.initial_data @@ -205,7 +205,7 @@ class InvenTreeCustomStatusSerializerMixin: setattr(self.instance, follower_field_name, self.initial_data[field]) # Mirror values from follower to leader - for field in self._custom_fields_follower: + for field in self._custom_fields_follower or []: leader_field_name = field.replace('_custom_key', '') if field in validated_data and leader_field_name not in self.initial_data: try: @@ -276,7 +276,7 @@ class InvenTreeCustomStatusSerializerMixin: # Inherit choices from leader self.gather_custom_fields() - if field_name in self._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] if hasattr(leader_field, 'choices'): diff --git a/src/backend/InvenTree/generic/states/tests.py b/src/backend/InvenTree/generic/states/tests.py index 17a2221d1f..fe33eaf78e 100644 --- a/src/backend/InvenTree/generic/states/tests.py +++ b/src/backend/InvenTree/generic/states/tests.py @@ -232,8 +232,8 @@ class ApiTests(InvenTreeAPITestCase): """Test the API endpoint for listing all status models.""" response = self.get(reverse('api-status-all')) - # 10 built-in state classes, plus the added GeneralState class - self.assertEqual(len(response.data), 11) + # 11 built-in state classes, plus the added GeneralState class + self.assertEqual(len(response.data), 12) # Test the BuildStatus model build_status = response.data['BuildStatus'] @@ -273,7 +273,7 @@ class ApiTests(InvenTreeAPITestCase): ) response = self.get(reverse('api-status-all')) - self.assertEqual(len(response.data), 11) + self.assertEqual(len(response.data), 12) stock_status_cstm = response.data['StockStatus'] self.assertEqual(stock_status_cstm['status_class'], 'StockStatus') diff --git a/src/backend/InvenTree/generic/states/transition.py b/src/backend/InvenTree/generic/states/transition.py index ab9c48c47b..80ae2f7f3c 100644 --- a/src/backend/InvenTree/generic/states/transition.py +++ b/src/backend/InvenTree/generic/states/transition.py @@ -63,7 +63,7 @@ class TransitionMethod: result: bool - True if the transition method was successful, False otherwise. Raises: - ValidationError: Alert the user that the transition failued + ValidationError: Alert the user that the transition failed """ raise NotImplementedError( 'TransitionMethod.transition must be implemented' diff --git a/src/backend/InvenTree/importer/api.py b/src/backend/InvenTree/importer/api.py index 5d3fd6a748..c64f71c654 100644 --- a/src/backend/InvenTree/importer/api.py +++ b/src/backend/InvenTree/importer/api.py @@ -73,6 +73,22 @@ class DataImportSessionMixin: serializer_class = importer.serializers.DataImportSessionSerializer permission_classes = [InvenTree.permissions.DataImporterPermission] + def get_queryset(self): + """Return the set of DataImportSession objects that the user has permission to view.""" + queryset = super().get_queryset() + + try: + user = self.request.user + except AttributeError: + raise PermissionDenied('User information is not available') + + # Allow staff users access to all DataImportSession objects + if user.is_staff: + return queryset + + # For non-staff users, only allow access to sessions that they have created + return queryset.filter(user=user) + class DataImportSessionList(BulkDeleteMixin, DataImportSessionMixin, ListCreateAPI): """API endpoint for accessing a list of DataImportSession objects.""" diff --git a/src/backend/InvenTree/importer/mixins.py b/src/backend/InvenTree/importer/mixins.py index 1a36982ed6..969f82afa2 100644 --- a/src/backend/InvenTree/importer/mixins.py +++ b/src/backend/InvenTree/importer/mixins.py @@ -24,11 +24,11 @@ class DataImportSerializerMixin: Determine if the serializer is being used for data import, and if so, adjust the serializer fields accordingly. """ - importing = kwargs.pop('importing', False) + self._is_importing = kwargs.pop('importing', False) super().__init__(*args, **kwargs) - if importing: + if self._is_importing: # Exclude any fields which are not able to be imported importable_field_names = list(self.get_importable_fields().keys()) field_names = list(self.fields.keys()) diff --git a/src/backend/InvenTree/importer/models.py b/src/backend/InvenTree/importer/models.py index 5fa96c96c3..8dae1376ab 100644 --- a/src/backend/InvenTree/importer/models.py +++ b/src/backend/InvenTree/importer/models.py @@ -152,7 +152,7 @@ class DataImportSession(models.Model): return supported_models().get(self.model_type, None) - def get_related_model(self, field_name: str) -> models.Model: + def get_related_model(self, field_name: str) -> Optional[models.Model]: """Return the related model for a given field name. Arguments: @@ -241,7 +241,7 @@ class DataImportSession(models.Model): ) # Create the column mappings - DataImportColumnMap.objects.bulk_create(column_mappings) + DataImportColumnMap.objects.bulk_create(column_mappings, batch_size=250) self.status = DataImportStatusCode.MAPPING.value self.save() @@ -337,7 +337,7 @@ class DataImportSession(models.Model): imported_rows.append(row) # Perform database writes as a single operation - DataImportRow.objects.bulk_create(imported_rows) + DataImportRow.objects.bulk_create(imported_rows, batch_size=250) # Mark the import task as "PROCESSING" self.status = DataImportStatusCode.PROCESSING.value @@ -394,7 +394,14 @@ class DataImportSession(models.Model): if serializer_class := self.serializer_class: serializer = serializer_class(data={}, importing=True) - fields.update(metadata.get_serializer_info(serializer)) + serializer_fields = metadata.get_serializer_info(serializer) + + for field_name, field in serializer_fields.items(): + # Skip read-only fields + if field.get('read_only', False): + continue + + fields[field_name] = field # Cache the available fields against this instance self._available_fields = fields @@ -552,6 +559,12 @@ class DataImportRow(models.Model): self.valid = self.validate() super().save(*args, **kwargs) + def delete(self, *args, **kwargs): + """Update the session progress when a row is deleted.""" + session = self.session + super().delete(*args, **kwargs) + session.check_complete() + session = models.ForeignKey( DataImportSession, on_delete=models.CASCADE, @@ -693,7 +706,7 @@ class DataImportRow(models.Model): if commit: self.save() - def convert_date_field(self, value: str) -> str: + def convert_date_field(self, value: str) -> Optional[str]: """Convert an incoming date field to the correct format for the database.""" if value in [None, '']: return None diff --git a/src/backend/InvenTree/importer/registry.py b/src/backend/InvenTree/importer/registry.py index 28d96d0a79..b57fe9e3ee 100644 --- a/src/backend/InvenTree/importer/registry.py +++ b/src/backend/InvenTree/importer/registry.py @@ -19,14 +19,14 @@ class DataImportSerializerRegister: def register(self, serializer) -> None: """Register a new serializer with the importer registry.""" if not issubclass(serializer, DataImportSerializerMixin): - logger.debug('Invalid serializer class: %s', type(serializer)) + logger.debug('Invalid serializer class: %s', serializer.__name__) return if not issubclass(serializer, Serializer): - logger.debug('Invalid serializer class: %s', type(serializer)) + logger.debug('Invalid serializer class: %s', serializer.__name__) return - logger.debug('Registering serializer class for import: %s', type(serializer)) + logger.debug('Registering serializer class for import: %s', serializer.__name__) if serializer not in self.supported_serializers: self.supported_serializers.append(serializer) diff --git a/src/backend/InvenTree/importer/tests.py b/src/backend/InvenTree/importer/tests.py index 97619c70a3..17490b9283 100644 --- a/src/backend/InvenTree/importer/tests.py +++ b/src/backend/InvenTree/importer/tests.py @@ -39,7 +39,7 @@ class ImporterTest(ImporterMixin, InvenTreeTestCase): session.extract_columns() - self.assertEqual(session.column_mappings.count(), 15) + self.assertEqual(session.column_mappings.count(), 14) # Check some of the field mappings for field, col in [ @@ -174,6 +174,36 @@ class ImportAPITest(ImporterMixin, InvenTreeAPITestCase): # Check that there are new database records self.assertEqual(PartCategory.objects.count(), N + 4) + def test_session_list(self): + """Test API endpoint which details the list of import sessions.""" + url = reverse('api-importer-session-list') + + # Construct a dummy file + f = self.helper_file('companies.csv') + + for ii in range(5): + DataImportSession.objects.create( + data_file=f, + model_type='company', + user=self.user if ii % 2 == 0 else None, + ) + + # Staff user should see all sessions + self.user.is_staff = True + self.user.save() + + response = self.get(url) + self.assertEqual(len(response.data), 5) + + # Non-staff user should only see sessions which they own + self.user.is_staff = False + self.user.save() + + response = self.get(url) + self.assertEqual(len(response.data), 3) + for session in response.data: + self.assertEqual(session['user'], self.user.pk) + class AdminTest(ImporterMixin, AdminTestCase): """Tests for the admin interface integration.""" diff --git a/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po index 39225c2040..3072988a23 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 20:21\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "نقطة نهاية API غير موجودة" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "المستخدم ليس لديه الصلاحية لعرض هذا النموذج" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "تعذّر تحويل {original} إلى {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "الكمية المقدمة غير صحيحة" @@ -112,13 +105,13 @@ msgstr "أدخل التاريخ" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "ملاحظات" @@ -131,75 +124,91 @@ msgstr "القيمة '{name}' لا تظهر في تنسيق النمط" msgid "Provided value does not match required pattern: " msgstr "القيمة المقدمة لا تتطابق مع النمط المطلوب: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "سلسلة الرقم التسلسلي فارغة" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "تكرار التسلسل" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "نطاق المجموعة {group} يتجاوز الكَمّيَّة المسموح بها ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "لم يتم العثور على أرقام متسلسلة" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "إزالة علامات HTML من هذه القيمة" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "خطأ فى الاتصال" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "البريد الإلكتروني" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po index 92cbfb52a0..66e0d275a0 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Bulgarian\n" "Language: bg_BG\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Не е намерена крайна точка на API" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Елементите трябва да се предоставят, като списък" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Филтрите следва да се предоставят, като dict" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Потребителя няма нужното разрешение, за да вижда този модел" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Преобразуването на {original} в {unit} не беше успешно" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Въведена е недопустима стойност" @@ -112,13 +105,13 @@ msgstr "Въведи дата" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Бележки" @@ -131,75 +124,91 @@ msgstr "Значението '{name}' не отговаря на шаблона" msgid "Provided value does not match required pattern: " msgstr "Въведеното значение не отговаря на задължителния шаблон: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Липсва сериен номер" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Повтарящ се сериен номер" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Не са открити серийни номера" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Премахнете HTML маркерите от тази стойност" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Грешка при съединението" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Сървърът отговари с невалиден статусен код" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Възникна изключение" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Сървърът отговори с невалидна стойност за дължината на съдържанието (Content-Length)" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Размерът на изображението е твърде голям" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Сваляното на изображение превиши максималния размер" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Отдалеченият сървър върна празен отговор" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Трябва да активирате двойно оторизиране преди да направите, каквото и да е." @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Китайски (опростен)" msgid "Chinese (Traditional)" msgstr "Китайски (традиционен)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Част" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Потребител" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Изпратено" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Цялостна наличност" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Място в склада" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Места в склада" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 a6497330b8..0d7fadec37 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint nebyl nalezen" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Seznam položek nebo filtrů musí být k dispozici pro hromadnou operaci" +#: InvenTree/api.py:438 +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:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Položky musí být uvedeny jako seznam" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Zadán neplatný seznam položek" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filtry musí být uvedeny jako slovník" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Poskytnuty neplatné filtry" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Všechny filtry musí být použity s Pravda" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Zadaným kritériím neodpovídají žádné položky" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nebyla poskytnuta žádná data" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Toto pole musí být unikátní." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Uživatel nemá právo zobrazit tento model" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Vyplněno neplatné množství" @@ -112,13 +105,13 @@ msgstr "Zadejte datum" msgid "Invalid decimal value" msgstr "Neplaté desetinné číslo" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Poznámky" @@ -131,75 +124,91 @@ msgstr "Hodnota '{name}' neodpovídá formátu vzoru" msgid "Provided value does not match required pattern: " msgstr "Poskytnutá hodnota neodpovídá požadovanému vzoru: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Nelze serializovat více než 1000 položek najednou" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Nevyplněné výrobní číslo" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplicitní výrobní číslo" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Neplatná skupina: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nenalezena žádná výrobní čísla" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Odstranit HTML tagy z této hodnoty" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Data obsahují zakázaný markdown obsah" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "Neplatná URH: žádný název hostitele" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "Neplatná URL: nelze zjistit název hostitele" + +#: InvenTree/helpers_model.py:120 +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 +msgid "Too many redirects" +msgstr "Příliš mnoho přesměrování" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Chyba spojení" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Server odpověděl s neplatným stavovým kódem" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Došlo k výjimce" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Server odpověděl s neplatnou hodnotou Content-Length" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Velikost obrázku je příliš velká" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Stahování obrázku překročilo maximální velikost" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Vzdálený server vrátil prázdnou odpověď" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Zadaná URL adresa není platný soubor obrázku" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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í." @@ -255,133 +264,108 @@ msgstr "Referenční číslo musí odpovídat požadovanému vzoru" msgid "Reference number is too large" msgstr "Referenční číslo je příliš velké" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Neplatný výběr" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Název" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Popis" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Popis (volitelně)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Cesta" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 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:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Poznámky (volitelné)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Data čárového kódu" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Data čárového kódu třetí strany" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash čárového kódu" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Jedinečný hash dat čárového kódu" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Nalezen existující čárový kód" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Selhání úlohy" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Úloha na pozadí '{f}' se ani po {n} pokusech nezdařila" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Chyba serveru" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Server zaznamenal chybu." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Musí být platné číslo" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Měna" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Vyberte měnu z dostupných možností" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Toto pole nesmí být nulové." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Neplatná hodnota" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Vzdálený obraz" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL souboru vzdáleného obrázku" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Stahování obrázků ze vzdálené URL není povoleno" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Nepodařilo se stáhnout obrázek ze vzdálené adresy URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Neplatný formát typu obsahu" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Typ obsahu nenalezen" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Typ obsahu neodpovídá požadované třídě mixinu" @@ -537,11 +521,11 @@ msgstr "Čínština (zjednodušená)" msgid "Chinese (Traditional)" msgstr "Čínština (tradiční)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Dostupná aktualizace" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Aktualizace pro InvenTree je k dispozici" @@ -553,30 +537,30 @@ msgstr "Neplatná fyzikální jednotka" msgid "Not a valid currency code" msgstr "Neplatný kód měny" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Stav objednávky" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Nadřazená sestava" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Zahrnout varianty" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Zahrnout varianty" msgid "Part" msgstr "Díl" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategorie" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Sestava předků" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Přiřazeno mě" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Přiřazeno" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Vytvořeno před" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Vytvořeno po" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Má počáteční datum" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Datum začátku před" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Datum začátku po" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Má cílové datum" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Cílové datum před" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Cílové datum po" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Dokončeno před" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Dokončeno po" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Min. datum" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Max datum" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Vyloučit strom" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Spotřební materiál" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Volitelné" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Sestava" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Sledováno" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testovatelné" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Objednávka nevyřízená" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Přiděleno" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Spotřebováno" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Na objednávku" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "Sestava nenalezena" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 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:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lokace" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Výstup" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Výrobní příkazy" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Kusovník sestavy ještě nebyl schválen" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Musí být specifikován odpovědný uživatel nebo skupina" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Díl výrobního příkazu nelze změnit" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Cílové datum musí být po datu zahájení" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referenční číslo výrobního příkazu" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referenční číslo výrobního příkazu" msgid "Reference" msgstr "Reference" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Stručný popis sestavení (nepovinné)" -#: build/models.py:275 +#: build/models.py:278 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:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Vyber téma, které chceš stavět" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referenční číslo prodejní objednávky" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Prodejní objednávka, které je tato stavba přiřazena" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Zdrojové umístění" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Externí sestavení" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Tento výrobní příkaz je plněn externě" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Cílová lokace" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Vyberte lokaci, kde budou dokončené položky uloženy" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Množství sestav" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Počet skladových položek k sestavení" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Dokončené položky" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Počet skladových položek, které byly dokončeny" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Stav sestavení" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Stavový kód sestavení" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Kód dávky" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Dávkový kód pro tento výstup sestavení" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Datum vytvoření" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Datum zahájení sestavení" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Plánované datum zahájení této objednávky" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Cílové datum dokončení" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Datum dokončení" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "dokončil" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Vystavil" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Uživatel, který vystavil tento výrobní příkaz" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odpovědný" -#: build/models.py:409 +#: build/models.py:420 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:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Externí odkaz" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Odkaz na externí URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Priorita sestavení" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Priorita tohoto výrobního příkazu" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Kód projektu" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Kód projektu pro tento výrobní příkaz" -#: build/models.py:686 +#: build/models.py:697 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:691 +#: build/models.py:702 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:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Výrobní příkaz byl dokončen" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nebyl specifikováno žádný výstup sestavení" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Výstup sestavení je již dokončen" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Výstup neodpovídá výrobnímu příkazu" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Množství musí být vyšší než nula" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 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:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "Přiřazené skladové položky jsou stále ve výrobě" -#: build/models.py:1208 +#: build/models.py:1221 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:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Řádková položka výrobního příkazu" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Vytvořit objekt" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Množství" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Vyžadované množství pro výrobní příkaz" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Množství spotřebovaných zásob" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Vybraná skladová položka neodpovídá řádku kusovníku" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "Přiřazené množství musí být vyšší než nula" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Množství musí být 1 pro zřetězený sklad" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Skladová položka je nadměrně zabrána" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Skladové položky" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Zdrojová skladová položka" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Skladové množství pro sestavení" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Instalovat do" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Cílová skladová položka" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Úroveň sestavení" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Název dílu" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Vytvořit výstup" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Vytvořený výstup neodpovídá nadřazenému sestavení" -#: build/serializers.py:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Výstup sestavení je již dokončen" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Tento stavební výstup není plně přiřazen" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Zadejte množství pro výstup sestavení" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Celé množství požadované pro sledovatelné díly" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Sériová čísla" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Zadejte sériová čísla pro sestavení výstupů" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Skladové umístění pro výstup sestavy" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automaticky zvolit sériová čísla" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Musí být uveden seznam výstupů sestavy" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Skladové umístění pro sešrotované výstupy" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Zahodit alokace" -#: build/serializers.py:495 +#: build/serializers.py:501 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:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Důvod vyřazení výstupu(ů) sestavy" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Umístění dokončených výstupů sestavy" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Přijmout neúplné přidělení" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Spotřebovat přidělené zásoby" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Odstranit neúplné výstupy" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Odstranit všechny výstupy sestavy, které nebyly dokončeny" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Není povoleno" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Přijmout jako spotřebované tímto výrobním příkazem" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Uvolnit před dokončením tohoto výrobního příkazu" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Nadměrně přidělené zásoby" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Některé skladové položky byly nadměrně přiděleny" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Přijmout nepřidělené" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Požadované zásoby nebyly plně přiděleny" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Přijmout neúplné" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Požadované množství sestavy nebylo dokončeno" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Výrobní příkaz má otevřené podpříkazy" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Výrobní příkaz musí být ve stavu produkce" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Výrobní příkaz má neúplné výstupy" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linka sestavy" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Výstup sestavy" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Výstup sestavy musí odkazovat na stejnou sestavu" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Řádková položka sestavy" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Položka musí být skladem" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Položky přidělení musí být poskytnuty" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Vynechat lokace" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Vyloučit skladové položky z tohoto vybraného umístění" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Zaměnitelné zásoby" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Náhradní zásoby" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Povolit přidělování náhradních dílů" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Volitelné položky" -#: build/serializers.py:1117 +#: build/serializers.py:1123 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:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "Všechny položky" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "Nesledované položky" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "Sledované položky" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "Typ položky" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Vyberte typ položky pro automatické přiřazení" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Nepodařilo se spustit úlohu automatického přidělování" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Reference v kusovníku" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID dílu kusovníku" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Název dílu kusovníku" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "Informace instalace" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Sestavení" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Díl dodavatele" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Přidělené množství" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Reference sestavení" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Název kategorie dílů" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Sledovatelné" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Zděděno" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Povolit varianty" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Položka kusovníku" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Ve výrobě" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Naplánováno na sestavení" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Externí zásoby" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Dostupné zásoby" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Dostupné náhradní zásoby" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Dostupná varianta skladu" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Spotřebované množství přesahuje přidělené množství" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Nepovinné poznámky ke spotřebě zásob" -#: build/serializers.py:1806 +#: build/serializers.py:1807 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:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Duplikovat přidělení položky sestavení" -#: build/serializers.py:1829 +#: build/serializers.py:1830 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:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Duplikovat přiřazení výrobní linky" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Musí být poskytnuta alespoň jedna linka nebo předmět" @@ -1495,43 +1479,47 @@ msgstr "Pozastaveno" msgid "Cancelled" msgstr "Zrušeno" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Hotovo" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Zásoby potřebné pro výrobní příkaz" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Výrobní příkaz {build} vyžaduje další zásoby" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Opožděný výrobní příkaz" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Objednávka sestavy {bo} je nyní opožděná" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Je odkaz" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Je soubor" -#: common/api.py:766 +#: common/api.py:777 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:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Uživatel nemá oprávnění k odstranění této přílohy" @@ -1551,798 +1539,822 @@ msgstr "Nejsou uvedeny žádné platné kódy měn" msgid "No plugin" msgstr "Žádný plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Popisek kódu projektu" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Aktualizováno" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Časové razítko poslední aktualizace" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Aktualizoval/a" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Uživatel, který naposledy aktualizoval tento objekt" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Jedinečný kód projektu" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Popis projektu" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Tlačítko nastavení" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Hodnota nastavení" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Zvolená hodnota není platnou možností" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Hodnota musí být logická hodnota" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Hodnota musí být celé číslo" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Hodnota musí být platné číslo" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Hodnota neprošla kontrolou platnosti" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Klíčový text musí být jedinečný" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Uživatel" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Množství cenové slevy" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Cena" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Jednotková cena při stanoveném množství" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Koncový bod" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Název tohoto webhooku" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktivní" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Je tento webhook aktivní" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token pro přístup" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Tajný klíč" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Sdílený tajný klíč pro HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID zprávy" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Unikátní identifikátor pro tuto zprávu" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Hostitel" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Hostitel, od kterého byla tato zpráva přijata" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Záhlaví" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Záhlaví této zprávy" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Tělo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Tělo zprávy" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Koncový bod, na kterém byla zpráva přijata" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Pracoval na" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Byla práce na této zprávě dokončena?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Název" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Odkaz" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Zveřejněno" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Souhrn" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Přečteno" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Byla tato novinka přečtena?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Soubor obrázku" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Cílový typ modelu pro tento obrázek" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "Cílové ID modelu pro tento obrázek" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Vlastní jednotka" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Symbol jednotky musí být unikátní" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Název jednotky musí být platný identifikátor" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Název jednotky" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Volitelný symbol jednotky" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definice" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definice jednotky" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Příloha" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Chybějící soubor" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Chybějící externí odkaz" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Typ modelu" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Cílový typ modelu pro obrázek" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Vyberte soubor k přiložení" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentář" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Komentář přílohy" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Datum nahrání" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Datum, kdy byl soubor nahrán" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Velikost souboru" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Velikost souboru v bytech" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Uveden neplatný typ modelu pro přílohu" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Vlastní stav" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Vlastní stavy" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Nastavení referenčního stavu" -#: common/models.py:2102 +#: common/models.py:2184 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:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logický klíč" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Hodnota" -#: common/models.py:2114 +#: common/models.py:2196 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:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Název stavu" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Popisek" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Štítek, který bude zobrazen na webu" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Barva" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Barva, která bude zobrazena ve frontendu" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Model, ke kterému je tento stav přiřazen" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Musí být vybrán model" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Musí být vybrán klíč" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Musí být vybrán logický klíč" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Klíč se musí lišit od logického klíče" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Musí být uvedena platná referenční třída statusu" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Výběrové pole" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Výběrová pole" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Název výběrového pole" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Popis výběrového pole" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Uzamčeno" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Je tento seznam výběrů uzamčen?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Může být tento seznam výběru použit?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Zdrojový plugin" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Plugin, který poskytuje seznam výběru" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Zdrojový řetězec" -#: common/models.py:2280 +#: common/models.py:2362 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:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Výchozí položka" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Výchozí položka pro tento seznam výběru" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Vytvořeno" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Datum a čas vytvoření výběrového seznamu" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Poslední aktualizace" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Položka seznamu výběrů" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Položky seznamu výběrů" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Seznam výběru, do kterého tato položka patří" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Název výběrového seznamu" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Popisek pro výběr seznamu" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Popis vstupu výběrového seznamu" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Je tento výběr výběrového listu aktivní?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Šablona parametru" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Šablona parametru" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Parametry zaškrtávacího pole nemohou mít jednotky" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Parametry zaškrtávacího pole nemohou mít výběr" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Volby musí být jedinečné" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Název šablony parametru musí být jedinečný" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Cílový typ modelu pro šablonu tohoto parametru" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Název parametru" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Jednotky" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Fyzické jednotky pro tento parametr" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Popis parametru" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Zaškrtávací políčko" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Je tento parametr zaškrtávací políčko?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Volby" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Platné volby pro tento parametr (oddělené čárkami)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Seznam výběru pro tento parametr" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Povoleno" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Je šablona tohoto parametru povolena?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Parametr" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Parametry" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Neplatná volba pro hodnotu parametru" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Neplatný typ modelu pro daný parametr" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "ID modelu" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "ID cílového modelu pro tento parametr" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Šablona" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Šablona parametru" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Data" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Hodnota parametru" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Poznámka" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Volitelné pole pro poznámku" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Sken čárového kódu" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Data čárového kódu" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Uživatel, který naskenoval čárový kód" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Časová značka" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Datum a čas skenování čárového kódu" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Koncový bod URL, který zpracoval čárový kód" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontext" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Kontextová data pro skenov čárového kódu" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Odpověď" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Data z odezvy z čárového kódu" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Výsledek" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Bylo skenování čárového kódu úspěšné?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Vyskytla se chyba" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "E-mailová zpráva" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "E-mailové zprávy" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Oznámeno" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Odesláno" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Selhalo" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Doručeno" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Potvrzeno" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Příchozí" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Odchozí" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Bez odpovědi" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Sledovat doručení" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Sledovat přečtení" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Sledovat kliknutí" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Globální ID" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID vlákna" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Vlákno" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Vlákno propojeno k této zprávě" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Priorita" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Emailové vlákno" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Emailové vlákna" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Klíč" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Unikátní identifikátor pro toto vlákno" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Začato interně" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Bylo toto vlákno započato interně?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Datum a čas kdy bylo vlákno vytvořeno" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Datum a čas kdy bylo vlákno naposledy aktualizováno" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Přijaté položky" @@ -2392,1235 +2404,1303 @@ msgstr "Indikuje zdali bylo nastavení přepsáno proměnou prostředí" msgid "Override" msgstr "Přepsat" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Je spuštěné" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Čekající úkoly" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Naplánované úlohy" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Neúspěšné úlohy" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID úlohy" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Unikátní ID úlohy" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Zamknout" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Čas uzamčení" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Jméno úkolu" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funkce" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Název funkce" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumenty" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumenty úlohy" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argumenty klíčových slov" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argumenty klíčových slov úlohy" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Název souboru" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Typ modelu" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: 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:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Žádná skupina" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Adresa URL webu je uzamčena konfigurací" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Je vyžadován restart" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Bylo změněno nastavení, které vyžaduje restart serveru" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Nevyřízené migrace" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Počet nevyřízených migrací databáze" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Aktivní varovací kódy" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Seznam aktivních varovacích kódů" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID instance" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Unikátní identifikátor pro tuto InvenTree instanci" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "ID oznámení" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Oznámit ID instance pro server na server status infu (nepřihlášeno)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Název instance serveru" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Textový popisovač pro instanci serveru" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Použít název instance" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Použít název instance v liště" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Omezit zobrazování `o aplikaci`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Zobrazovat okno `o aplikaci` pouze superuživatelům" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "Zobrazit banner superuživatele" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "Zobrazit varovný banner v uživatelském rozhraní při přihlášení jako superuživatel" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "Zobrazit banner administrátora" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "Zobrazit varovný banner v uživatelském rozhraní při přihlášení jako administrátor" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Jméno společnosti" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Interní název společnosti" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Základní URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Základní URL pro instanci serveru" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Výchozí měna" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Vyberte základní měnu pro cenové kalkulace" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Podporované měny" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Seznam podporovaných kódů měn" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Interval aktualizace měny" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dny" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Plugin aktualizace měny" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Plugin pro aktualizaci měn k použití" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Stáhnout z URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Povolit stahování vzdálených obrázků a souborů z externích URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limit velikosti stahování" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maximální povolená velikost stahování vzdáleného obrázku" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-agent použitý ke stažení z adresy URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Povolit přepsání user-agenta používaného ke stahování obrázků a souborů z externí adresy URL (ponechte prázdné pro výchozí)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Přísná validace URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Vyžadovat specifikaci schématu při ověřování adres URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Interval kontroly aktualizací" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Jak často kontrolovat aktualizace (nastavte na nulu pro vypnutí)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatické Zálohování" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Povolit automatické zálohování databáze a mediálních souborů" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Interval automatického zálohování" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Zadejte počet dní mezi automatickými zálohovými událostmi" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Interval mazání úloh" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Výsledky úloh na pozadí budou odstraněny po zadaném počtu dní" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Interval odstranění protokolu chyb" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Záznamy chyb budou odstraněny po zadaném počtu dní" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Interval pro odstranění oznámení" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Uživatelská oznámení budou smazána po zadaném počtu dní" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Interval mazání emailů" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Emailové zprávy budou odstraněny po specifikovaném počtu dní" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Chránit Email log" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Zabránit odstranění vstupů email logů" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Podpora čárových kódů" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Povolit podporu pro skenování čárových kódů ve webovém rozhraní" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Ukládat výsledky čárových kódů" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Ukládat výsledky skenování čárových kódů v databázi" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maximální počet naskenovaných čárových kódů" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Maximální počet uložených výsledků skenování čárových kódů" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Zpoždění vstupu čárového kódu" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Doba zpoždění zpracování vstupu čárového kódu" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Podpora webové kamery pro čárové kódy" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Povolit skenování čárových kódů přes webovou kameru v prohlížeči" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Zobrazovat data čárových kódů" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Zobrazovat data čárových kódů v prohlížeči jako text" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Plugin pro generování čárových kódů" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revize dílu" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Povolit pole revize pro díl" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Revize pouze pro sestavy" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Povolit revize pouze pro sestavy" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Povolit odstranění ze sestavy" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Povolit duplicitní IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Povolit více dílům sdílet stejný IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Povolit editaci IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Kopírovat data BOM dílu" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Kopírovat data parametrů dílu" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Kopírovat zkušební data dílu" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kopírovat šablony parametrů kategorie" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Díly jsou ve výchozím nastavení šablony" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Možné zakoupit" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Díly jsou zakoupitelné ve výchozím nastavení" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Prodejné" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Díly jsou prodejné ve výchozím nastavení" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Díly jsou sledovatelné ve výchozím nastavení" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Nehmotné (virtuální)" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Díly jsou nehmotné (virtuální) ve výchozím nastavení" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Zobrazit související díly" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Zobrazit související díly pro díl" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Počáteční údaje zásob" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Počáteční údaje dodavatele" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formát zobrazení jména dílu" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formát pro zobrazení názvu dílu" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Výchozí ikona kategorie dílu" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Minimální počet desetinných míst u cen" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Maximální počet desetinných míst u cen" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Použít ceny dodavatele" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Přepsání historie nákupu" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Použít ceny skladových položek" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Stáří cen skladových položek" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Použít cenu varianty" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Zahrnutí cen variant do celkových cenových kalkulací" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Pouze aktivní varianty" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Automatická aktualizace cen" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Interval přestavby cen" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interní ceny" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Povolit interní ceny pro díly" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Přepis interní ceny" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "Povolit nulovou hodnotu kusovníku" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Povolit tisk štítků" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Povolit tisk štítků z webového rozhraní" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI rozlišení štítků" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Povolit reporty" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Povolit generování reportů" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Režim ladění chyb" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Generovat reporty v režimu ladění (HTML výstup)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Zaznamenávat chyby reportů" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Zaznamenávat chyby, které se vyskytnou při vytváření reportů" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Velikost stránky" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Výchozí velikost stránky pro PDF reporty" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Vynutit jednotky parametru" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globálně unikátní sériová čísla" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Odstranit vyčerpané zásoby" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "Odstranit serializované zásoby" + +#: common/setting/system.py:707 +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 msgid "Batch Code Template" msgstr "Šablona kódu dávky" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Expirace zásob" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Povolit funkci expirace zásob" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Prodat prošlé zásoby" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Povolit prodej prošlých zásob" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Čas stáří zásob" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Sestavit prošlé zásoby" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Povolit sestavování s prošlými zásobami" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Kontrola vlastnictví zásob" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Výchozí ikona umístění zásob" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Zobrazit nainstalované skladové položky" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Zobrazit nainstalované skladové položky ve skladových tabulkách" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Zkontrolovat BOM při instalaci položek" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Povolit převod mimo sklad" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Referenční vzor objednávky sestavy" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Vyžadovat odpovědného vlastníka" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Ke každé objednávce musí být přiřazen odpovědný vlastník" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Vyžadovat aktivní díl" -#: common/setting/system.py:778 +#: common/setting/system.py:791 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:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Vyžadovat uzamčený díl" -#: common/setting/system.py:784 +#: common/setting/system.py:797 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:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Vyžadovat schválený kusovník" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Vyžadovat uzavření podobjednávek" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Externí výrobní příkazy" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Povolit funkcionalitu externích výrobních příkazů" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "Vyžadovat externí výrobní příkazy" + +#: common/setting/system.py:824 +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 msgid "Block Until Tests Pass" msgstr "Blokovat, dokud testy neprojdou" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Povolit vracení objednávek" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Referenční vzor návratové objednávky" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Úprava dokončených návratových objednávek" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Referenční vzor prodejní objednávky" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Výchozí přeprava prodejní objednávky" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Úprava dokončených prodejních objednávek" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Zásilka vyžaduje kontrolu" -#: common/setting/system.py:873 +#: common/setting/system.py:894 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:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Označit odeslané objednávky jako dokončené" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" +msgstr "Blokovat nekompletné testy položky" + +#: common/setting/system.py:910 +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 msgid "Purchase Order Reference Pattern" msgstr "Referenční vzor nákupní objednávky" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Úprava dokončených nákupních objednávek" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Převést měnu" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Automatické dokončování nákupních objednávek" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Povolit pole zapomenutého hesla" -#: common/setting/system.py:925 +#: common/setting/system.py:954 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Povolit registrace" -#: common/setting/system.py:931 +#: common/setting/system.py:960 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Povolit SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Povolit SSO na přihlašovacích stránkách" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Povolit SSO registraci" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Povolit synchronizaci SSO skupin" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "klíč SSO skupiny" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "mapa SSO skupiny" -#: common/setting/system.py:966 +#: 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 "Mapování ze skupin SSO do místních InvenTree skupin. Pokud místní skupina neexistuje, bude vytvořena." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Odstranit skupiny mimo SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Vyžadován e-mail" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Požadovat, aby uživatel při registraci zadal e-mail" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Automaticky vyplnit SSO uživatele" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Mail dvakrát" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Heslo dvakrát" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Povolené domény" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Skupina při registraci" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Vynutit MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Uživatelé musí používat vícefaktorové zabezpečení." -#: common/setting/system.py:1026 +#: 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 "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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Zkontrolovat pluginy při spuštění" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Zkontrolovat aktualizace pluginů" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Povolit pravidelné kontroly aktualizací nainstalovaných pluginů" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Povolit integraci URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Povolit plug-inům přidávat trasy URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Povolit integraci navigace" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Povolit integrování pluginů do navigace" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Povolit integraci aplikací" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Povolit pluginům přidávát aplikace" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Povolit integraci plánu" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Povolit pluginům spouštění naplánovaných úloh" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Povolit integraci událostí" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Povolit pluginům reagovat na interní události" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Povolit rozhraní intergace" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Povolit integrování pluginů do uživatelského rozhraní" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Povolit integraci emailu" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Povolit pluginům zpracování odchozích/příchozích emailů" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Povolit projektové kódy" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Povolit projektové kódy pro sledování projektů" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "Povolit inventuru" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Vyloučit externí umístění" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 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:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Perioda automatické inventury" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "Počet dní mezi automatickým záznamem inventury" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "Odstranit staré záznamy inventur" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 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:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "Interval odstranění inventury" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 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:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "Odstranit staré záznamy sledování zásob" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 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:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "Interval odstranění sledování zásob" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 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:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Zobrazit celá jména uživatelů" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Zobrazit uživatelské profily" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Zobrazit profily uživatelů na jejich profilové stránce" -#: common/setting/system.py:1171 +#: common/setting/system.py:1200 +msgid "Week Starts On" +msgstr "Týden začíná" + +#: common/setting/system.py:1201 +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 +msgid "Sunday" +msgstr "Neděle" + +#: common/setting/system.py:1205 +msgid "Monday" +msgstr "Pondělí" + +#: common/setting/system.py:1206 +msgid "Tuesday" +msgstr "Úterý" + +#: common/setting/system.py:1207 +msgid "Wednesday" +msgstr "Středa" + +#: common/setting/system.py:1208 +msgid "Thursday" +msgstr "Čtvrtek" + +#: common/setting/system.py:1209 +msgid "Friday" +msgstr "Pátek" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "Sobota" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Povolit data zkušební stanice" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Povolit ping stroje" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Povolit pravidelný úkol pingu registrovaných strojů pro kontrolu jejich stavu" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "Zobrazit podsestavy v tabulce kusovníku" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "Povolit zobrazení podsestav v tabulce kusovníku" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Přijímat zprávy o chybách" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Dostávat oznámení o systémových chybách" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Poslední použité tiskárny" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "Zobrazit položky na poslední úrovni" + +#: common/setting/user.py:274 +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 msgid "All models" msgstr "Všechny modely" @@ -3965,365 +4061,369 @@ msgstr "Díl je aktivní" msgid "Manufacturer is Active" msgstr "Výrobce je aktivní" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Díl dodavatele je aktivní" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "Primární díl dodavatele" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Interní díl je aktivní" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Dodavatel je aktivní" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Výrobce" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Společnost" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Má zásoby" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Společnosti" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Popis společnosti" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Popis společnosti" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Webová stránka" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Webové stránky společnosti" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefonní číslo" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kontaktní telefonní číslo" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontaktní e-mailová adresa" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Kontaktní místo" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Odkaz na externí informace o společnosti" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Je tato společnost aktivní?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Je zákazník" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Prodáváte zboží této společnosti?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Je dodavatel" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Zakupujete zboží od této společnosti?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Je výrobce" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Vyrábí tato společnost díly?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Výchozí měna používaná pro tuto společnost" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "DIČ" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "DIČ společnosti" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adresa" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adresy" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Vyberte společnost" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Název adresy" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Název popisující záznam adresy" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Primární adresa" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Nastavit jako primární adresu" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Řádek 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "1. řádek adresy" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Řádek 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "2. řádek adresy" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "PSČ" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Město/Region" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "PSČ město/region" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Stát/kraj" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Stát nebo provincie" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Země" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adresovaná země" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Doručovací poznámky pro kurýra" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Poznámky pro kurýra" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Interní přepravní poznámky" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Doručovací poznámky pro interní použití" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Odkaz na informace o adrese (externí)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Výrobce dílu" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Základní díl" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Zvolte díl" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Vyberte výrobce" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Číslo dílu výrobce" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL pro odkaz na díl externího výrobce" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Popis dílu výrobce" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Jednotky balení musí být větší než nula" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dodavatel" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Vyberte dodavatele" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Skladová evidence dodavatele" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Je tento díl dodavatele aktivní?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "Primární" -#: company/models.py:788 +#: company/models.py:793 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:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Vyberte díl výrobce" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Adresa URL pro odkaz na externí díl dodavatele" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Popis dílu dodavatele" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "základní cena" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimální poplatek (např. poplatek za skladování)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Balení" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Balení dílu" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Počet kusů v balení" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "více" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Objednat více" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Množství dostupné od dodavatele" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Dostupnost aktualizována" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Datum poslední aktualizace údajů o dostupnosti" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Cenová sleva dodavatele" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Výchozí měna používaná pro tohoto dodavatele" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Jméno společnosti" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Skladem" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Množstevní sleva" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "Hezké jméno" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Při exportu dat došlo k chybě" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Existující databázový identifikátor pro tento záznam" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Sloupec je již napamován k poli databáze" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Pole je již namapováno do datového sloupce" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Sloupec neexistuje v datovém souboru" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Pole neexistuje v cílovém modelu" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Vybrané pole je pouze pro čtení" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Importovací relace" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Pole" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Sloupec" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Index řádku" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Původní data řádku" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Chyby" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Platné" -#: importer/models.py:833 +#: 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:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Žádný záznam nalezen pro zadané ID" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Poskytnut neplatný formát ID" @@ -4588,7 +4688,7 @@ msgstr "Počet kopií, které se mají tisknout pro každý štítek" msgid "Connected" msgstr "Připojeno" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Neznámý" @@ -4692,7 +4792,7 @@ msgstr "Klíč vlastnosti" msgid "Value of the property" msgstr "Hodnota vlastnosti" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Skupina" @@ -4720,7 +4820,7 @@ msgstr "Maximální hodnota pro pokrok typu, vyžadováno pokud typ=pokrok" msgid "Order Reference" msgstr "Označení objednávky" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Vynikající" @@ -4728,7 +4828,7 @@ msgstr "Vynikající" msgid "Has Project Code" msgstr "Má projektový kód" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Vytvořil(a)" @@ -4764,57 +4864,69 @@ msgstr "Cílové datum před" msgid "Target Date After" msgstr "Cílové datum po" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "Aktualizováno před" + +#: order/api.py:236 +msgid "Updated After" +msgstr "Aktualizováno po" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Má cenu" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Dokončeno před" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Dokončeno po" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Externí výrobní příkaz" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Objednávka" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Objednávka byla dokončena" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Interní díl" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Objednávka čeká na vyřízení" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Dokončeno" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Má zásilku" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +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 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Nákupní objednávka" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Nákupní objednávka" msgid "Sales Order" msgstr "Prodejní objednávka" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Celková cena" msgid "Total price for this order" msgstr "Celková cena za tuto objednávku" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Měna objednávky" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Měna pro tuto objednávku (nechte prázdné pro použití výchozí hod msgid "This order is locked and cannot be modified" msgstr "Tato objednávka je uzamčena a nelze ji upravit" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Kontakt nesouhlasí s vybranou společností" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Datum zahájení musí být před cílovým datem" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "Adresa nesouhlasí s vybranou společností" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Popis objednávky (volitelné)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Vyberte kód projektu pro tuto objednávku" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Odkaz na externí stránku" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Datum zahájení" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Plánované datum zahájení této objednávky" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Cílené datum" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Datum vystavení" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Datum vystavení objednávky" #: order/models.py:506 +msgid "Updated At" +msgstr "Aktualizováno v" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Uživatel nebo skupina odpovědná za tuto objednávku" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Kontaktní bod pro tuto objednávku" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Adresa společnosti pro tuto objednávku" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Číslo objednávky" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Stav" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Stav objednávky" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Společnost, od které se položky objednávají" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Reference dodavatele" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Referenční kód objednávky dodavatele" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "přijal" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Datum dokončení objednávky" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Místo určení" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Cílové místo pro přijaté položky" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Dodavatel dílu se musí shodovat s dodavatelem PO" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Řádková položka neodpovídá nákupní objednávce" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Řádkové položce chybí propojený díl" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Množství musí být kladné" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Zákazník" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Společnost, jíž se položky prodávají" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Stav prodejní objednávky" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Reference zákazníka " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Referenční kód objednávky zákazníka" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Datum odeslání" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "odesláno společností" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Objednávka je již dokončena" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Objednávka je již zrušena" -#: order/models.py:1423 +#: order/models.py:1463 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:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Objednávka je uzamčena a nelze ji upravit" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Množství položky" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "Číslo linky" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "Číslo řádku pro tuto položku (nepovinné)" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Označení řádkové položky" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Poznámky k řádkovým položkám" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Popis řádkové položky (nepovinné)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Dodatečný kontext pro tento řádek" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Cena za jednotku" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Řádková položka nákupní objednávky" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Dodavatelský díl musí odpovídat dodavateli" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Objednávka sestavení musí být označená jako externí" -#: order/models.py:1904 +#: order/models.py:1971 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:1910 +#: order/models.py:1977 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:1945 +#: order/models.py:1987 +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 msgid "Supplier part" msgstr "Díl dodavatele" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Doručeno" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Počet přijatých položek" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Nákupní cena" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Jednotková nákupní cena" -#: order/models.py:1978 +#: order/models.py:2056 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:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Nákupní příkaz extra linka" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Řádková položka prodejní objednávky" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Prodejní cena" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Jednotková prodejní cena" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Odesláno" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Odeslané množství" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Zásilka prodejní objednávky" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "Adresa zásilky musí odpovídat adrese zákazníka" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Dodací adresa pro tuto zásilku" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Datum odeslání" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Datum doručení" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Datum doručení zásilky" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Kontroloval(a)" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Uživatel, který zkontroloval tuto zásilku" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Doprava" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Číslo zásilky" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Sledovací číslo" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informace o sledování zásilky" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Číslo faktury" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Referenční číslo přiřazené faktury" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Zásilka již byla odeslána" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Zásilka nemá žádné přidělené skladové položky" -#: order/models.py:2389 +#: order/models.py:2477 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:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Prodejní příkaz extra linka" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Přidělení prodejní objednávky" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Skladová položka nebyla přiřazena" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Přidělené množství nesmí překročit množství zásob" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Zabrané množství musí být větší než nula" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Množství musí být 1 pro serializovanou skladovou položku" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Prodejní objednávka neodpovídá zásilce" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Zásilka neodpovídá prodejní objednávce" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Řádek" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Odkaz na zásilku z prodejní objednávky" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Položka" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Vyberte skladovou položku pro přidělení" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Zadejte množství pro přidělení zásob" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Reference návratové objednávky" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Společnost, od které se vrací položky" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Stav návratové objednávky" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Linkový předmět vratky" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Zásobní položka musí být specifikována" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Množství vratky přesahuje množstvní zásob" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Množstvní vratky musí být více než nula" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Neplatné množství pro sériovou skladovou položku" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Vyberte položku pro vrácení od zákazníka" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Datum přijetí" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "Datum příjetí této vratky" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Výsledek" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Výsledky pro tuto položku" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Vratka extra linka" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID objednávky" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID objednávky k duplikaci" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Kopírovat řádky" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Kopírovat řádkové položky z původní objednávky" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Kopírovat extra řádky" -#: order/serializers.py:95 +#: 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/serializers.py:110 +#: order/serializers.py:96 part/serializers.py:414 +msgid "Copy Parameters" +msgstr "Kopírovat parametry" + +#: order/serializers.py:97 +msgid "Copy order parameters from the original order" +msgstr "Kopírovat parametry objednávky z původní objednávky" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Řádkové položky" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Dokončené řádky" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplikovat objednávku" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Specifikujte možnosti pro duplikaci této objednávky" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Neplatné ID objednávky" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Název dodavatele" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Objednávku nelze zrušit" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Objednávka má nedokončené řádkové položky" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Objednávka není otevřena" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automatická cena" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Měna nákupní ceny" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Sloučit položky" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Číslo zboží (SKU)" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Interní číslo dílu" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Interní název dílu" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Musí být uveden díl dodavatele" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Objednávka musí být zadána" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Dodavatel musí odpovídat objednávce" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Objednávka musí odpovídat dodavateli" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Řádková položka" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Vyberte cílové umístění pro přijaté položky" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Zadat kód šarže pro příchozí skladové položky" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Datum expirace" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Zadejte datum expirace pro příchozí skladové položky" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Zadat sériová čísla pro příchozí skladové položky" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Přepsat informace o obalu pro příchozí skladové položky" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Dodatečná poznámka pro příchozí skladové položky" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Čárový kód" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Naskenovaný čárový kód" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Tento čárový kód se již používá" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Musí být uvedeny řádkové položky" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Místo určení musí být specifikováno" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Hodnoty dodaných čárových kódů musí být unikátní" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Zásilky" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Dokončené zásilky" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "Přidělené řádky" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Měna prodejní ceny" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Přidělené položky" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nebyly poskytnuty žádné údaje o zásilce" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Množství musí být kladné" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +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 msgid "Enter serial numbers to allocate" msgstr "Zadejte sériová čísla pro přidělení" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Zásilka již byla odeslána" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Zásilka není spojena s touto objednávkou" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Následující sériová čísla nejsou k dispozici" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Řádkový předmět vratky" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Řádková položka neodpovídá vratce" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Řádková položka již byla přijata" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Množství k vrácení" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Měna ceny řádku" @@ -5598,146 +5742,150 @@ msgstr "Vrácení peněz" msgid "Reject" msgstr "Odmítnout" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Objednávka po splatnosti" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Nákupní objednávka {po} je nyní opožděná" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Opožděná prodejní objednávka" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Prodejní objednávka {so} je nyní opožděná" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Vratka po termínu vrácení" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Vratka {ro} je nyní opožděná" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Označené" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filtrovat podle kategorií s hvězdičkou" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Hloubka" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtrovat podle hloubky kategorie" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Nejvyšší úroveň" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtrovat podle nejvyšších kategorií" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Kaskáda" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Zahrnout podkategorie do filtrovaných výsledků" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Předek" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filtrovat podle nadřazené kategorie" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Vyloučit podkategorie v zadané kategorii" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Má výsledky" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Je varianta" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Je revizí" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Má revize" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Kusovník schválen" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Kaskádové kategorie" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filtrovat podle numerického ID kategorie nebo doslovného 'null'" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "Sestavený díl je aktivní" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "Sestavený díl je sledovatelný" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Sestavený díl je testovatelný" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "Sestavený díl je uzamčen" + +#: part/api.py:1316 msgid "Component part is active" msgstr "Kompotenta je aktivní" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "Komponenta je sledovatelná" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Díl komponenty je testovatelný" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "Komponenta je část sestavy" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "Komponenta je virtuální" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "Má dostupné zásoby" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Využití" @@ -5746,11 +5894,11 @@ msgstr "Využití" msgid "Part Category" msgstr "Kategorie dílu" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Kategorie dílů" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Výchozí umístění" @@ -5778,7 +5926,7 @@ msgstr "Výchozí klíčová slova pro díly v této kategorii" msgid "Icon" msgstr "Ikona" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikona (volitelná)" @@ -5799,1025 +5947,1050 @@ msgstr "Výchozí hodnota" msgid "Default Parameter Value" msgstr "Výchozí hodnota parametru" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Díly" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Nelze odstranit parametry zamčeného dílu" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Nelze upravit parametry zamčeného dílu" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Tento díl nelze smazat, protože je uzamčen" -#: part/models.py:593 +#: part/models.py:594 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:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN musí odpovídat regex vzoru {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Díl nemůže být revize same sebe" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Nelze udělat revizi dílu, který už je revize" +#: part/models.py:784 +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:790 -msgid "Revision code must be specified" -msgstr "Kód revize musí být uveden" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Revize jsou povoleny pouze pro sestavy" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Nelze provést revizi šablony" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Nadřazený díl musí odkazovat na stejnou šablonu" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplicitní IPN není povoleno v nastavení dílu" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Duplicitní díl revize již existuje." -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 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:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Název dílu" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Je šablonou" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Je tento díl šablona?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Je tento díl varianta jiného dílu?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Varianta" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Popis dílu (nepovinné)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Klíčová slova" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Klíčová slova dílu pro zlepšení vyhledávání" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Kategorie dílu" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Interní číslo dílu (IPN)" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Číslo revize nebo verze dílu" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revize" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Je tento díl revizí jiného dílu?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Revize" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Kde je tato položka obvykle skladněna?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Výchozí expirace" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimální zásoby na skladě" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimální povolená úroveň zásob" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "Maximální zásoby" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "Maximální povolená úroveň zásob" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Měrné jednotky pro tento díl" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Lze tento díl sestavit z jiných dílů?" -#: part/models.py:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Lze u tohoto dílu sledovat jednotlivé položky?" -#: part/models.py:1272 +#: part/models.py:1276 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:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Lze tento díl prodávat zákazníkům?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Je tento díl aktivní?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Uzamčené díly nelze upravit" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Kusovník ověřen" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Je kusovník pro tuto část platný?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Kontrolní součet kusovníku" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Uložený kontrolní součet kusovníku" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Kusovník zkontroloval" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Datum kontroly kusovníku" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Vytváření uživatele" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Vlastník odpovědný za tento díl" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Prodat více" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Měna použitá pro výpočet cen v mezipaměti" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimální cena kusovníku" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minimální cena komponent dílu" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maximální cena kusovníku" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maximální cena komponent dílu" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimální nákupní cena" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimální historická nákupní cena" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maximální nákupní cena" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maximální historická nákupní cena" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimální interní cena" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimální cena závislá na množstevní slevě" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maximální interní cena" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maximální cena závislá na množstevní slevě" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimální cena dodavatele" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Minimální cena dílu od externích dodavatelů" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maximální cena dodavatele" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maximální cena dílu od externích dodavatelů" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimální cena variant" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Vypočítané minimální náklady na varianty dílů" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maximální cena variant" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Vypočítané maximální náklady na varianty dílů" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimální cena" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Přepsat minimální náklady" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maximální cena" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Přepsat maximální náklady" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Vypočítané minimální celkové náklady" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Vypočítané maximální celkové náklady" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimální prodejní cena" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Minimální prodejní cena na základě cenových zvýhodnění" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maximální prodejní cena" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maximální prodejní cena na základě cenových zvýhodnění" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimální prodejní cena" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimální historická prodejní cena" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maximální prodejní cena" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maximální historická prodejní cena" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Díl na inventuru" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Počet položek" -#: part/models.py:3473 +#: part/models.py:3487 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:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Celkové dostupné zásoby v době inventury" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Datum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Datum provedení inventury" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimální cena zásob" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Odhadovaná minimální cena zásob k dispozici" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maximální cena zásob" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Odhadovaná maximální cena zásob k dispozici" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Částeční sleva v ceně" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Šablona testu položky" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Zkušební šablony lze vytvořit pouze pro testovatelné části" -#: part/models.py:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Název testu" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Zadejte název testu" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Testovací klíč" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Zjednodušený klíč pro testování" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Popis testu" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Zadejte popis pro tento test" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Je tento test povolen?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Požadováno" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Je tato zkouška vyžadována k projití?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Požadovaná hodnota" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Vyžaduje přílohu" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Platné volby pro tento test (oddělené čárkami)" -#: part/models.py:3954 +#: part/models.py:3918 +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 +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 msgid "BOM item cannot be modified - assembly is locked" msgstr "Položku kusovníku nelze změnit - sestava je uzamčena" -#: part/models.py:3961 +#: part/models.py:4030 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:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Vyberte nadřazený díl" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Poddílec" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Vyberte díl které bude použit v kusovníku" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "Množství" + +#: part/models.py:4058 +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 msgid "BOM quantity for this BOM item" msgstr "Kusovníkové množství pro tuto kusovníkovou položku" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Tato položka kusovníku je nepovinná" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Nastavit množství" -#: part/models.py:4014 +#: part/models.py:4091 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:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Přirozené ztráty" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Zaokrouhlení více" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Reference položky kusovníku" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Poznámky k položce kusovníku" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Kontrolní součet" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Kontrolní součet řádku kusovníku" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Schváleno" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Tato položka kusovníku ještě nebyla schválena" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Se zdědí" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Množství musí být celé číslo pro sledovatelné díly" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Poddíl musí být specifikován" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Náhradní položka kusovníku" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Nadřazená položka kusovníku" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Náhradní díl" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Díl 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Díl 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Vyberte související díl" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Poznámka pro tento vztah" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Duplicitní vztah již existuje" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Nadřazená kategorie" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Nadřazená kategorie dílu" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Podkategorie" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Výsledky" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Počet výsledků zaznamenaných podle této šablony" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Nákupní měna této skladové položky" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Soubor není obrázek" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Původní díl" -#: part/serializers.py:384 +#: 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:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopírovat obrázek" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Kopírovat obrázek z původního dílu" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Kopírovat kusovník" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Kopírovat parametry" - -#: part/serializers.py:404 +#: 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:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Kopírovat poznámky" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Kopírovat poznámky z původního dílu" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Kopírovat testy" -#: part/serializers.py:418 +#: 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:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Počáteční skladové množství" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Počáteční skladové místo" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Zadejte počáteční skladové místo pro tento díl" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Vyberte dodavatele (nebo nechte prázdné pro přeskočení)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Vyberte výrobce (nebo nechte prázdné pro přeskočení)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Číslo dílu výrobce" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Vybraná společnost není platný dodavatel" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Vybraná společnost není platný výrobce" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Výrobce dílu se stejným MPN již existuje" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Dodavatelský díl s tímto SKU již existuje" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Název kategorie" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Budova" -#: part/serializers.py:816 +#: part/serializers.py:843 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:823 +#: part/serializers.py:850 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:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Skladové položky" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revize" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Celkem skladem" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Nezařazené zásoby" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Skladové varianty" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Duplikovat díl" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kopírovat počáteční data z jiného dílu" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Počáteční zásoby" -#: part/serializers.py:931 +#: part/serializers.py:977 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:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Informace o dodavateli" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Přidat počáteční informace dodavatele pro tento díl" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kopírovat parametry kategorie" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Kopírovat šablony parametrů z vybrané kategorie dilu" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Stávající obrázek" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Název souboru existujícího obrázku dílu" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Obrázek neexistuje" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Schválit celý kusovník" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Lze postavit" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Vyžadováno pro výrobní objednávku" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Přířazeno výrobním objednávkám" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Vyžadováno pro prodejní objednávky" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Přiřazeno prodejním objednávkám" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "IPN dílu" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "Popis dílu" -#: part/serializers.py:1288 +#: part/serializers.py:1327 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:1298 +#: part/serializers.py:1337 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:1308 +#: part/serializers.py:1347 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:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "Generovat vstupy inventury" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "Uložit vstupy inventury pro vybrané díly" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "Generovat report" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "Generovat report inventury pro vybrané díly" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimální cena" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Přespat vypočítanou hodnotu pro minimální cenu" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Měna minimální ceny" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maximální cena" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Přespat vypočítanou hodnotu pro maximální cenu" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Měna maximální ceny" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Aktualizovat" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Aktualizovat cenu pro díl" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +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 msgid "Select the parent assembly" msgstr "Vybrat nadřazenou sestavu" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Vyberte komponentu dílu" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "Neplatný formát množství" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Vyberte díl pro kopírování kusovníku z" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Odstranit existující data" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Odstranit existující položky kusovníku před kopírováním" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Zahrnout zděděné" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Přeskočit neplatné řádky" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Povolte tuto možnost pro přeskočení neplatných řádků" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Kopírovat náhradní díly" -#: part/serializers.py:1924 +#: part/serializers.py:2016 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:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Oznámení o nízkých zásobách" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Oznámení o zastaralých zásobách" -#: part/tasks.py:77 +#: part/tasks.py:78 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:79 +#: part/tasks.py:80 #, 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:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Bez data expirace" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "Expirovalo před {abs(days_diff)} dny" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Expiruje dnes" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dní" @@ -7031,15 +7204,15 @@ msgstr "Množství k přidělení" msgid "Label printing failed" msgstr "Tisk štítku se nezdařil" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Chyba při vykreslování štítku do PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Chyba při vykreslování štítku do HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Nejsou k dispozici žádné položky k tisku" @@ -7100,7 +7273,7 @@ msgstr "Poskytuje nativní podporu pro čárové kódy" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Oznámení o změně dílu" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "Díl '{part.name}' byl spuštěn událostí '{part_action}'" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree tiskárna PDF štítků" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Poskytuje nativní podporu pro tisk PDF štítků" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Režim ladění" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Povolit režim ladění - vrátí HTML místo PDF" @@ -7500,7 +7673,7 @@ msgstr "Rámeček" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Na šířku" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Pouze pracovníci mohou spravovat pluginy" +#: plugin/installer.py:240 plugin/installer.py:344 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 msgid "Plugin installation is disabled" msgstr "Instalace pluginu je zakázana" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +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 +msgid "Invalid characters in package name or URL" +msgstr "Neplatné znaky v názvu balíčku nebo v URL" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin byl úspěšně nainstalován" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin nainstalovaný do {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Plugin nebyl nalezen v registru" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Plugin není plugin balíček" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Název balíčku pluginu nebyl nalezen" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Pouze pracovníci mohou spravovat pluginy" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Odinstalace pluginu je zakázána" -#: plugin/installer.py:341 +#: plugin/installer.py:351 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:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Plugin nemůže být odinstalován, protože je povinný" -#: plugin/installer.py:352 +#: plugin/installer.py:362 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:357 +#: plugin/installer.py:367 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:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Plugin není nainstalován" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Inslalace pluginu nebyla nalezena" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Plugin odinstalován úspěšně" @@ -7689,21 +7875,21 @@ msgstr "Balíčkový plugin" msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nebyl nalezen žádný autor" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin vyžaduje alespoň verzi {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin vyžaduje nanejvýš verzi {v}" @@ -7884,55 +8070,55 @@ msgstr "Instalace nebyla potvrzena" msgid "Either packagename or URL must be provided" msgstr "Musí být uveden název balíčku nebo URL" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Plné načtení" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Provede plné načtení registru pluginů" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Vynutit přenačtení" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Vynutit přenačtění registru pluginů, i když je jich načten" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Sbírat pluginy" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Sbírat pluginy a přidávat je do registru" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Aktivovat plugin" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Aktivovat tento plugin" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Povinný plugin nemůže být vypnut" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Odstranit nastavení" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Odstranit konfiguraci pluginu z databáze" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "Uživatel pro kterého platí toto nastavení" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Položky" @@ -7948,7 +8134,7 @@ msgstr "Plugin nepodporuje tisk štítků" msgid "Invalid label dimensions" msgstr "Neplatné rozměry štítku" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Žádné platné položky nebyly k šabloně poskytnuté" @@ -7972,152 +8158,156 @@ msgstr "Letter" msgid "Template file with this name already exists" msgstr "Šablona s tímto názvem již existuje" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Název šablony" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Popis šablony" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Číslo revize (automatické navýšení)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Připojit k modelu při tisku" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Šablona pro názvy souborů" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Šablona pro generování názvů souborů" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Šablona je povolena" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Cílový typ modelu pro šablonu" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtry" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Vzorový soubor" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Velikost stránky pro PDF reporty" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Vykreslit report v orientaci na šířku" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Sloučit" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Vykreslit jeden report proti vybraným položkám" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Report generován ze šablony {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Chyba syntaxe šablony" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Chyba při vykreslování reportu" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Chyba při generování reportu" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Chyba při slučování výstupů reportu" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Šířka [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Šířka štítku zadaná v mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Výška [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Výška štítku uvedená v mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Chyba při tisku štítků" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Úryvek" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Nahlásit soubor úryvku" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Popis souboru úryvku" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Aktivum" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Nahlásit soubor aktiva" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Popis souboru aktiva" -#: report/serializers.py:95 +#: report/serializers.py:37 +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 msgid "Select report template" msgstr "Vybrat šablonu reportu" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "Seznam primárních klíčů k zahrnutí v reportu" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Vybrat šablonu pro štítek" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Tiskový plugin" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Vybrat plugin pro tisk štítků" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sériové číslo" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Instalované položky" @@ -8248,184 +8438,196 @@ msgstr "Žádný výsledek (povinný)" msgid "No result" msgstr "Žádný výsledek" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Soubor aktiva neexistuje" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "Neplatná cesta k media souboru" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "Neplatná cesta ke statickému souboru" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "Soubor aktiva nebyl nalezen" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Soubor obrázku nebyl nalezen" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "Nebyl zadán žádný obrázek" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image tag vyžaduje instanci dílu" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image tag vyžaduje intanci společnosti" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filtrovat dle hloubky lokace" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Filtrovat dle nejvyšší lokace" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Zahrnout pod-lokace ve filtrovaných výsledcích" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Nadřazená místo" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtrovat podle nadřazené lokace" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Název dílu (citlivost písmen na malá a velká písmena)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Název dílu obsahuje (citlivost písmen na malá a velká písmena)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Název dílu (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "IPN dílu (citlivost písmen na malá a velká písmena)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "IPN dílu obsahuje (citlivost písmen na malá a velká písmena)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "IPN dílu (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Minimální zásoby" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Maximální zásoby" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Kód stavu" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Externí umístění" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Spotřebováno výrobním příkazem" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Nainstalováno v jiné skladové položce" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Strom dílů" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Aktualizováno před" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Aktualizováno po" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Inventura před" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Inventura po" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Datum expirace ped" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Datum expirace po" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Zastaralé" -#: stock/api.py:963 +#: 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:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "Umístění kaskády" -#: stock/api.py:982 +#: stock/api.py:981 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:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Filtrovat podle numberické ID lokace nebo doslovného 'null'" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Množství je povinné" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Platný díl musí být dodán" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Daný dodavatelský díl neexistuje" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "Zahrnout nainstalované" -#: stock/api.py:1403 +#: stock/api.py:1411 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:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "Filtrovat podle číselného ID položky skladu" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Skladová položka s ID {id} neexistuje" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "Zahrnout varianty" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "Datum po" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "Datum před" @@ -8441,19 +8643,19 @@ msgstr "Typy skladových umístění" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Skladové umístění" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Skladová umístění" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Správce" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Vybrat vlastníka" @@ -8461,7 +8663,7 @@ msgstr "Vybrat vlastníka" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Externí" @@ -8481,274 +8683,282 @@ msgstr "Typ tohoto skladového umístění" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "Serializované zásoby nelze odstranit" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} neexistuje" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Díl musí být zadán" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Nelze vytvořit skladovou položku pro virtuální díl" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Položka nemůže patřit sama sobě" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Stavební reference neukazuje na stejný objekt dílu" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Nadřazená skladová položka" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Základní díl" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Kde se tato skladová položka nachází?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Balení, ve kterém je tato skladová položka uložena" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Instalováno v" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Je tato položka nainstalována v jiné položce?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Sériové číslo pro tuto položku" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Kód šarže pro tuto skladovou položku" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Mnižství" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Zdrojová sestavení" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Postavit pro tuto skladovou položku" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Použito v" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Výrobní příkaz, který spotřeboval tuto skladovou položku" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Zdrojová nákupní objednávka" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Nákupní objednávka pro tuto skladovou položku" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Cílová prodejní objednávka" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Odstranit po vyčerpání" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Odstranit tuto skladovou položku po vyčerpání zásob" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Jednotková kupní cena v okamžiku nákupu" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Převedeno na díl" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "Množství přesahuje dostupné zásoby" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Díl není nastaven jako sledovatelný" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Množstvní musí být celé číslo" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Sériové čísla musí být poskytnuta jako seznam" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Množství neodpovídá sériovým číslům" -#: stock/models.py:1934 +#: 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:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Testovací šablona neexistuje" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Skladová položka byla přidělena prodejní objednávce" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Skladová položka je nainstalována v jiné položce" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Skladová položka obsahuje jiné položky" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Skladová položka byla přidělena zákazníkovi" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Skladová položka je ve výrobě" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Serializované zásoby nelze sloučit" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Duplicitní skladové položky" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Skladové položky musí odkazovat na stejný díl" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Skladové položky musí odkazovat na stejný díl dodavatele" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Kódy stavu zásob se musí shodovat" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Sledování skladových položek" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Poznámky k záznamu" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Výsledek testu skladové položky" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Pro tuto zkoušku musí být uvedena hodnota" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Pro tento test musí být nahrána příloha" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Neplatná hodnota pro tento test" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Výsledek testu" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Výstupní hodnota testu" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Příloha výsledků testu" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Poznámky testu" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Testovací stanice" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "Identifikátor testovací stanice kde byl test proveden" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Začátek" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Čas začátku testu" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Ukončeno" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Čas dokončení testu" @@ -8792,246 +9002,246 @@ msgstr "Vyberte díl, pro který se má vygenerovat sériové číslo" msgid "Quantity of serial numbers to generate" msgstr "Množství sériových čísel k vygenerování" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Testovací šablona pro tento výsledek" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "Pro tento díl nebyl nalezen žádný odpovídající test" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "ID šablony nebo název testu musí být uveden" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Nadřazená položka" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Nadřazená skladová položka" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "Použít velikost balení" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Zadejte sériová čísla pro nové položky" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Číslo dílu dodavatele" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Expirováno" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Podřízené položky" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Sledování položky" -#: stock/serializers.py:643 +#: stock/serializers.py:668 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:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Zadejte počet skladových položek k serializaci" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "Nebyla poskytnuta žádná skladová položka" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Cílové skladové umístění" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "K tomuto dílu nelze přiřadit sériová čísla" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Sériová čísla již existují" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Vyberte skladovou položku k instalaci" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Množství k instalaci" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Zadejte množství položek k instalaci" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Přidat poznámku o transakci (volitelné)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Množství k instalaci musí být alespoň 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Skladová položka je nedostupná" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Vybraný díl není v kusovníku" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Množství k instalaci nesmí překročit dostupné množství" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Cílové umístění pro odinstalovanou položku" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Stavový kód skladové položky" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Vybrat skladové položky pro změnu stavu" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Nejsou vybrány žádné skladové položky" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Podumístění" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Nadřazené skladové umístění" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Díl musí být prodejný" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Položka je přidělena prodejní objednávce" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Položka je přidělena výrobnímu příkazu" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Zákazník, kterému mají být přiděleny skladové položky" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Vybraná společnost není zákazník" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Poznámky ke skladové položce" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Musí být poskytnut seznam skladových položek" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Poznámky ke sloučení skladových položek" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Povolit neodpovídající dodavatele" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Povolit neodpovídající stav" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Musí být poskytnuty alespoň dvě skladové položky" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Beze změny" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Hodnota primárního klíče skladové položky" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Skladová položka není skladem" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "Skladová položka je již na skladě" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "Množství nesmí být záporné" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Poznámky ke skladovací transakci" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "Sloučit do existující zásoby" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 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:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Další sériové číslo" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Předchozí sériové číslo" @@ -9369,227 +9579,247 @@ msgstr "Čas posledního použití tokenu" msgid "Revoked" msgstr "Zrušeno" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Nastavení oprávnění" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Zobrazit" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Oprávnění k zobrazení položek" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Přidat" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Oprávnění přidat položky" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Změnit" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Oprávnění k úpravě položek" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Odstranit" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Oprávnění k odstranění položek" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Bot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Interní" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Host" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Jazyk" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Preferovaný jazyk uživatele" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Motiv" -#: users/models.py:514 +#: users/models.py:512 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:519 +#: users/models.py:517 msgid "Widgets" msgstr "Widgety" -#: users/models.py:521 +#: users/models.py:519 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:528 +#: users/models.py:526 msgid "Display Name" msgstr "Zobrazované jméno" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Zvolené zobrazované jméno pro uživatele" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Pozice" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Název nebo funkce hlavního zaměstnání" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Zpráva statusu uživatele" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Informace o umístění uživatele" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "Uživatel aktivně používá systém" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Upřednostňované kontaktní údaje pro uživatele" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Typ uživatele" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Jaký typ uživatele to je?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organizace" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Primární organizace / přidružení uživatelů" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Primární skupina" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Primární skupina uživatele" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administrátor" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "Kusovník" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Zakoupené objednávky" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Prodejní objednávky" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Návratové objednávky" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Uživatelské jméno" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Křestní jméno" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Křestní jméno uživatele" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Příjmení" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Příjmení uživatele" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Emailová adresa uživatele" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personál" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "Uživatel musí být autentizován" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Má tento uživatel oprávnění personálu" +#: users/serializers.py:249 +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:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "Administrátor" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "Má tento uživatel administrativní oprávnění" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Super-uživatel" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Je tento uživatel superuživatel" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Je tento uživatelský účet aktivní" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Pouze superuživatel může toto pole upravit" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Heslo" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Heslo uživatele" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Přepsat varování" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Přepsat varování o pravidlech pro heslo" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "Personál" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "Má tento uživatel oprávnění personálu" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Nemáte oprávnění k vytváření uživatelů" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Váš účet byl vytvořen." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Pro přihlášení použijte funkci obnovení hesla" -#: users/serializers.py:452 +#: users/serializers.py:497 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 25e9c3126a..8934869d8d 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 20:21\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint ikke fundet" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Liste af elementer eller filtre skal angives for bulkdrift" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Elementer skal angives som en liste" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Alle filtre må kun bruges med sand" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Ingen data angivet" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Dette felt skal være unikt." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Bruger har ikke tilladelse til at se denne model" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Ugyldigt antal angivet" @@ -112,13 +105,13 @@ msgstr "Angiv dato" msgid "Invalid decimal value" msgstr "Ugyldig decimalværdi" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Bemærkninger" @@ -131,75 +124,91 @@ msgstr "Værdi '{name}' vises ikke i mønsterformat" msgid "Provided value does not match required pattern: " msgstr "Den angivne værdi matcher ikke det påkrævede mønster: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Kan ikke serialisere mere end 1000 elementer på én gang" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Serienummer streng er tom" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplikeret serienummer" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ugyldig gruppe: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Ingen serienumre fundet" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Fjern HTML-tags fra denne værdi" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Data indeholder forbudt markdown indhold" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Forbindelsesfejl" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serveren svarede med ugyldig statuskode" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Der opstod en fejl" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serveren svarede med ugyldig Content-Length værdi" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Billedstørrelsen er for stor" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Billeddownload overskred maksimumstørrelsen" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Fjernserver returnerede tomt svar" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Angivet URL er ikke en gyldig billedfil" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "Reference skal matche det påkrævede mønster" msgid "Reference number is too large" msgstr "Referencenummer er for stort" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Ugyldigt valg" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Navn" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Beskrivelse" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Beskrivelse (valgfri)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Sti" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown noter (valgfri)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Stregkode Data" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Tredjeparts stregkode data" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Stregkode Hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unik hash af stregkode data" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Eksisterende stregkode fundet" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverfejl" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "En fejl blev logget af serveren." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Skal være et gyldigt tal" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Vælg valuta fra tilgængelige muligheder" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Dette felt kan ikke være tomt." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Ugyldig værdi" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Eksternt billede" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL til ekstern billedfil" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Download af billeder fra ekstern URL er ikke aktiveret" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kinesisk (forenklet)" msgid "Chinese (Traditional)" msgstr "Kinesisk (traditionelt)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Opdatering tilgængelig" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "En opdatering til InvenTree er tilgængelig" @@ -553,30 +537,30 @@ msgstr "Ugyldig fysisk enhed" msgid "Not a valid currency code" msgstr "Ikke en gyldig valutakode" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Ordre status" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Overordnet produktion" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategori" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Tildelt til Mig" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Tildelt Til" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Oprettet før" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Oprettet efter" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Har startdato" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Start dato før" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Start dato efter" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Produktion skal anulleres, før den kan slettes" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Forbrugsvare" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Valgfri" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Sporet" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Ordre Udestående" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Allokeret" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Produktionsordre" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lokation" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Produktionsordrer" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Monteringens stykliste er ikke blevet valideret" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Ansvarlig bruger eller gruppe skal specificeres" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Byggeordre enhed kan ikke ændres" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Produktionsordre reference" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Produktionsordre reference" msgid "Reference" msgstr "Reference" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Vælg dele til produktion" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Salgsordrereference" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Kilde Lokation" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Ekstern Byg" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Denne byggeordre er gennemført eksternt" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Destinations Placering" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Produktions antal" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Antal lagervarer som skal produceres" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Afsluttede elementer" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Antal lagervarer som er færdiggjort" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Produktions Status" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Produktions statuskode" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Batch Kode" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Batch kode til dette produktions output" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Oprettelsesdato" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Planlagt startdato for denne byggeordre" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Projekteret afslutningsdato" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Dato for afslutning" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "udført af" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Udstedt af" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Bruger som udstedte denne byggeordre" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarlig" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Bruger eller gruppe ansvarlig for denne byggeordre" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Ekstern link" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link til ekstern URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Bygge Prioritet" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioritet af denne byggeordre" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Projektkode" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Projektkode for denne byggeordre" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Bygningsordre {build} er fuldført" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "En byggeordre er fuldført" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antal" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Lagervarer" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Kilde lagervare" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Del Navn" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Indtast serienumre for bygge output" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automatisk alloker serienumre" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Følgende serienumre findes allerede eller er ugyldige" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Ikke tilladt" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Accepter som forbrugt af denne byggeordre" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Accepter Ikke tildelt" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Accepter ufuldført" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Bygge linje" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Varen skal være på lager" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Stykliste Reference" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "Stykliste del ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Stykliste Del Navn" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Byg" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Leverandør Del" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Tildelt Antal" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Stykliste Del" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "I Produktion" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Ekstern Lager" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Tilgængelig Lager" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "På Hold" msgid "Cancelled" msgstr "Annulleret" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Fuldført" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "Ingen plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Projekt Kode Label" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Opdateret" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unik projekt kode" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projektbeskrivelse" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Værdien skal være en boolsk værdi" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Værdi skal være et heltalsværdi" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Skal være et gyldigt tal" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Værdien består ikke valideringskontrol" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Nøglestrengen skal være unik" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Bruger" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Pris" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktiv" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token for adgang" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Hemmelighed" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Besked ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Vært" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Vært, hvorfra denne meddelelse blev modtaget" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Overskrift" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Overskrift for denne besked" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titel" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Tilknytning" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publiceret" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Forfatter" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Opsummering" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Læs" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Blev dette nyhedselement læst?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Billedfil" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Vedhæftning" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Manglende fil" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Manglende eksternt link" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Vælg fil, der skal vedhæftes" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Filstørrelse" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Filstørrelse i bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Værdi" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Numerisk værdi, der vil blive gemt i modeldatabasen" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Farve" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Farve der vil blive vist på frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Låst" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Parameter skabelon navn skal være unikt" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Stregkode Scan" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Stregkode data" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Sendt" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Fejlede" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Leveret" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Bekræftet" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Indkommende" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Udgående" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Intet Svar" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Spor Levering" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Spor Læst" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Spor Klik" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "Tråd ID" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "E-mail Tråd" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "E-mail Tråde" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Nøgle" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Filnavn" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Firmanavn" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Standardvaluta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Liste over understøttede valutakoder" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Valuta Opdaterings Interval" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maksimum tilladte downloadstørrelse for fjernbillede" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Afsendt" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "Refusion" msgid "Reject" msgstr "Afvis" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Fornavn på brugeren" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Efternavn" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Efternavn på brugeren" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Email adresse på brugeren" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personale" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Har denne bruger personale tilladelser" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superbruger" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Er denne bruger en superbruger" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Er denne brugerkonto aktiv" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Kun en superbruger kan justere dette felt" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Adgangskode" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Brugers adgangskode" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Tilsidesæt advarsel" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Tilsidesæt advarslen om adgangskode regler" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Du har ikke tilladelse til at oprette brugere" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Din konto er oprettet." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Benyt funktionen til nulstilling af adgangskode til at logge ind" -#: users/serializers.py:452 +#: users/serializers.py:497 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 7bb5550c7b..227a6855f3 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 20:21\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API-Endpunkt nicht gefunden" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Liste der Elemente oder Filter muss für den Massenbetrieb zur Verfügung stehen" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Elemente müssen als Liste angegeben werden" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Ungültige Artikelliste angegeben" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filter müssen als Dict gegeben sein" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Ungültige Filter angegeben" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Alle Filter dürfen nur mit true verwendet werden" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Keine Gegenstände erfüllen die vorgegebenen Kriterien" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Keine Daten verfügbar" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Dieses Feld muss eindeutig sein." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Benutzer hat keine Berechtigung, dieses Modell anzuzeigen" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" @@ -112,13 +105,13 @@ msgstr "Datum eingeben" msgid "Invalid decimal value" msgstr "Ungültiger Dezimalwert" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notizen" @@ -131,75 +124,91 @@ msgstr "Wert '{name}' hält das Musterformat nicht ein" msgid "Provided value does not match required pattern: " msgstr "Angegebener Wert entspricht nicht dem benötigten Muster: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Kann nicht mehr als 1000 Elemente auf einmal serialisieren" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Keine Seriennummer angegeben" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplizierter Seriennummer" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ungültige Gruppe: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Keine Seriennummern gefunden" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Entferne HTML-Tags von diesem Wert" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Daten enthalten verbotene Markdown-Inhalte" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Verbindungsfehler" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Server antwortete mit ungültigem Statuscode" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Ausnahme aufgetreten" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Server antwortete mit ungültigem Wert für die Inhaltslänge" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Bild ist zu groß" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Bilddownload überschreitet maximale Größe" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Remote-Server gab leere Antwort zurück" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Angegebene URL ist kein gültiges Bild" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Referenz muss erforderlichem Muster entsprechen" msgid "Reference number is too large" msgstr "Referenznummer ist zu groß" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Ungültige Auswahl" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Name" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Beschreibung" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Beschreibung (optional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Pfad" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Doppelte Namen können nicht unter dem selben Elternteil existieren" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown Notizen (optional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Barcode-Daten" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Drittanbieter-Barcode-Daten" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Barcode-Hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Eindeutiger Hash der Barcode-Daten" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Bestehender Barcode gefunden" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Aufgabe fehlgeschlagen" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Hintergrundarbeiteraufgabe '{f}' fehlgeschlagen nach {n} Versuchen" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverfehler" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Ein Fehler wurde vom Server protokolliert." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Muss eine gültige Nummer sein" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Währung" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Währung aus verfügbaren Optionen auswählen" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Dieses Feld darf nicht leer sein." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Ungültiger Wert" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Grafiken aus externen Quellen" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL der Remote-Bilddatei" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Das Herunterladen von Bildern von Remote-URLs ist nicht aktiviert" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Fehler beim Herunterladen des Bildes von entfernter URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Content type stimmt nicht mit der benötigten Mixin-Klasse überein" @@ -537,11 +521,11 @@ msgstr "Chinesisch (Vereinfacht)" msgid "Chinese (Traditional)" msgstr "Chinesisch (Traditionell)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Update verfügbar" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Ein Update für InvenTree ist verfügbar" @@ -553,30 +537,30 @@ msgstr "Ungültige physikalische Einheit" msgid "Not a valid currency code" msgstr "Kein gültiger Währungscode" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Bestellstatus" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Eltern-Bauauftrag" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Varianten einschließen" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Varianten einschließen" msgid "Part" msgstr "Teil" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategorie" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Vorgänger-Build" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Mir zugewiesen" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Zugewiesen zu" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Erstellt vor" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Erstellt nach" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Hat Startdatum" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Gültigkeitsdauer vor" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Gültigkeitsdauer nach" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "geplantes Bestelldatum" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Zieldatum vor" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Zieldatum nach" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Abgeschlossen vor" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Abgeschlossen nach" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Baum ausschließen" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Bauauftrag muss abgebrochen werden, bevor er gelöscht werden kann" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Verbrauchsmaterial" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Optional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Baugruppe" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Nachverfolgt" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Prüfbar" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Offene Bestellung" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Zugeordnet" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Verbraucht" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Bestellt" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Bauauftrag" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lagerort" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Bauprodukt" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Bauaufträge" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Die Stückliste wurde noch nicht kontrolliert" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Baureihenfolge kann nicht für ein inaktives Teil erstellt werden" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Baureihenfolge kann nicht für ein inaktives Teil erstellt werden" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Verantwortlicher Benutzer oder Gruppe muss angegeben werden" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Teil in Bauauftrag kann nicht geändert werden" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Zieldatum muss nach dem Startdatum liegen" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Bauauftragsreferenz" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Bauauftragsreferenz" msgid "Reference" msgstr "Referenz" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Kurze Beschreibung des Baus (optional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Teil für den Bauauftrag wählen" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Auftrag Referenz" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Quell-Lagerort" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Ziel-Lagerort" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Lagerort an dem fertige Objekte gelagert werden auswählen" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Bau-Anzahl" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Anzahl der zu bauenden Lagerartikel" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Fertiggestellte Teile" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Anzahl der fertigen Lagerartikel" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Bauauftrags-Status" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Bau-Statuscode" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Losnummer" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Losnummer für dieses Endprodukt" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Erstelldatum" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Startdatum des Bauauftrags" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Geplantes Startdatum des Bauauftrags" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "geplantes Fertigstellungsdatum" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Zieldatum für Bauauftrag-Fertigstellung." -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Fertigstellungsdatum" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "Fertiggestellt von" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Aufgegeben von" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Nutzer der diesen Bauauftrag erstellt hat" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Verantwortlicher Benutzer" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Benutzer oder Gruppe verantwortlich für diesen Bauauftrag" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Externer Link" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Bauauftrags-Priorität" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Priorität dieses Bauauftrags" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Projektcode" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Projektcode für diesen Auftrag" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Bauauftrag {build} wurde fertiggestellt" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Ein Bauauftrag wurde fertiggestellt" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Seriennummern müssen für nachverfolgbare Teile angegeben werden" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "kein Endprodukt angegeben" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Endprodukt bereits hergstellt" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Endprodukt stimmt nicht mit dem Bauauftrag überein" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Menge kann nicht größer als die Ausgangsmenge sein" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Bauauftragsposition" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Objekt bauen" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Anzahl" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Erforderliche Menge für Auftrag" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Ausgewählter Lagerbestand stimmt nicht mit BOM-Linie überein" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Anzahl muss 1 für Objekte mit Seriennummer sein" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "BestandObjekt ist zu oft zugewiesen" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Lagerartikel" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Quell-Lagerartikel" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Anzahl an Lagerartikel dem Bauauftrag zuweisen" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Installiere in" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Ziel-Lagerartikel" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Name des Teils" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Endprodukt" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Endprodukt stimmt nicht mit übergeordnetem Bauauftrag überein" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Endprodukt entspricht nicht dem Teil des Bauauftrags" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Dieses Endprodukt wurde bereits fertiggestellt" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Dieses Endprodukt ist nicht vollständig zugewiesen" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Menge der Endprodukte angeben" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Ganzzahl für verfolgbare Teile erforderlich" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Seriennummer" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Seriennummer für dieses Endprodukt eingeben" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Lagerort für Bauprodukt" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Seriennummern automatisch zuweisen" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Benötigte Lagerartikel automatisch mit passenden Seriennummern zuweisen" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Die folgenden Seriennummern existieren bereits oder sind ungültig" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Eine Liste von Endprodukten muss angegeben werden" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Lagerort für ausgemusterte Ausgänge" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Zuteilungen verwerfen" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Bestandszuteilung für ausgemusterte Endprodukte verwerfen" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Grund für das Verwerfen des Bauauftrages/der Bauaufträge" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Lagerort für fertige Endprodukte" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Unvollständige Zuweisung akzeptieren" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Endprodukte fertigstellen, auch wenn Bestand nicht fertig zugewiesen wurde" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Zugewiesen Bestand verbrauchen" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Unfertige Endprodukte entfernen" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Lösche alle noch nicht abgeschlossenen Endprodukte" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Nicht erlaubt" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Als von diesem Bauauftrag verbraucht setzen" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Bestandszuordnung vor dem Abschluss dieses Bauauftrags freigeben" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Überbelegter Lagerbestand" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Der Bestand einiger Lagerartikel ist überbelegt" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Nicht zugewiesene akzeptieren" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Benötigter Bestand wurde nicht vollständig zugewiesen" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Unvollständig Zuweisung akzeptieren" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Benötigte Teil-Anzahl wurde noch nicht fertiggestellt" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Bauauftrag hat unvollständige Aufbauten" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Bauauftragsposition" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Endprodukt" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Endprodukt muss auf den gleichen Bauauftrag verweisen" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Bauauftragspositionsartikel" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Teil muss auf Lager sein" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Zuweisungen müssen angegeben werden" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Lagerort ausschließen" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Lagerartikel vom ausgewählten Ort ausschließen" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Wechselbares Lagerbestand" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Lagerartikel an mehreren Standorten können austauschbar verwendet werden" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Ersatzbestand" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Zuordnung von Ersatzteilen erlauben" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Optionale Positionen" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Optionale Stücklisten-Positionen dem Bauauftrag hinzufügen" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "Alle Artikel" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "Unverfolgte Artikel" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "Verfolgte Artikel" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "Item-Typ" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "Elementtyp zur automatischen Zuweisung auswählen" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Fehler beim Starten der automatischen Zuweisung" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Stücklisten-Referenz" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "Stückliste Teil-ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Stückliste Teil-Name" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Zusammenbau" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Zuliefererteil" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Zugewiesene Menge" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Teilkategorienname" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Nachverfolgbar" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Vererbt" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Varianten zulassen" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Stücklisten-Position" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "In Produktion" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Geplant zum Erstellen" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Externes Lager" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Verfügbarer Bestand" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Verfügbares Ersatzmaterial" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Verfügbarer Varianten Lagerbestand" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Verbrauchsmenge überschreitet die zugewiesene Menge" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Optionale Notizen für den Bestandsverbrauch" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Dupliziere Bauauftrag Artikelzuordnung" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Mindestens ein Element oder eine Zeile muss angegeben werden" @@ -1495,43 +1479,47 @@ msgstr "Pausiert" msgid "Cancelled" msgstr "Storniert" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Fertig" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Bestand für Bauauftrag erforderlich" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Bauauftrag {build} erfordert zusätzlichen Bestand" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Überfälliger Bauauftrag" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Bauauftrag {bo} ist jetzt überfällig" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Link" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Datei" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Benutzer hat keine Berechtigung zum Löschen der Anhänge" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Benutzer hat keine Berechtigung zum Löschen des Anhangs" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "Kein Plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Aktualisiert" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Zeitstempel der letzten Aktualisierung" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Eindeutiger Projektcode" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projektbeschreibung" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Benutzer oder Gruppe verantwortlich für dieses Projekt" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Einstellungs-Wert" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Wert ist keine gültige Option" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Wahrheitswert erforderlich" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Nur Ganzzahl eingeben" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Schlüsseltext muss eindeutig sein" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Benutzer" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Preisstaffelungs Anzahl" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Preis" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Stückpreis für die angegebene Anzahl" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Endpunkt" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Endpunkt, an dem dieser Webhook empfangen wird" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Name für diesen Webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktiv" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Ist dieser Webhook aktiv" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token für Zugang" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Geheimnis" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Shared Secret für HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Nachrichten-ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Eindeutige Kennung für diese Nachricht" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Host von dem diese Nachricht empfangen wurde" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Kopfzeile" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Header dieser Nachricht" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Body" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Body dieser Nachricht" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endpunkt, über den diese Nachricht empfangen wurde" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Bearbeitet" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Wurde die Arbeit an dieser Nachricht abgeschlossen?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titel" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Veröffentlicht" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Zusammenfassung" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Gelesen" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Wurde diese Nachricht gelesen?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Bilddatei" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Benutzerdefinierte Einheit" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Einheitensymbol muss eindeutig sein" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Einheitsname muss eine gültige Kennung sein" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Einheitsname" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Optionales Einheitssymbol" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definition" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Einheitsdefinition" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Anhang" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Fehlende Datei" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Fehlender externer Link" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Modelltyp" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Datei zum Anhängen auswählen" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Upload Datum" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Datum der hochgeladenen Datei" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Dateigröße" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Dateigröße in Bytes" -#: common/models.py:2074 common/serializers.py:715 +#: 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:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Wert" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Name des Bundeslandes" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Bezeichnung" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Bezeichnung, die im Frontend angezeigt wird" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Farbe" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Farbe, die im Frontend angezeigt wird" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Auswahlliste" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Auswahllisten" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Name der Auswahlliste" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Beschreibung der Auswahlliste" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Gesperrt" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Ist diese Auswahlliste gesperrt?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Kann diese Auswahlliste benutzt werden?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Standardeintrag" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Erstellt" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Zuletzt aktualisiert" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Checkbox-Parameter können keine Einheiten haben" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox-Parameter können keine Auswahl haben" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Auswahl muss einzigartig sein" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Name des Parameters" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Einheiten" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Physikalische Einheiten für diesen Parameter" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Parameter-Beschreibung" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Checkbox" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Ist dieser Parameter eine Checkbox?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Auswahlmöglichkeiten" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Gültige Optionen für diesen Parameter (durch Kommas getrennt)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Aktiviert" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Ungültige Auswahl für Parameterwert" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Vorlage" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Wert" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Parameter Wert" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Notiz" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Optionales Notizfeld" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Barcode Scan" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Zeitstempel" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontext" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Ergebnis" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Angekündigt" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Gesendet" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Fehlgeschlagen" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Zugestellt" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Bestätigt" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Eingehend" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Ausgehend" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Keine Rückmeldung" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Schlüssel" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Artikel erhalten" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Wird ausgeführt" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Anstehende Aufgaben" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Geplante Aufgaben" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Fehlgeschlagene Aufgaben" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Aufgabe-ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Eindeutige Aufgaben-ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Sperren" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Sperrzeit" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Aufgabenname" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funktion" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funktionsname" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Parameter" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Aufgaben-Parameter" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Schlüsselwort Parameter" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Schlüsselwort Parameter für Aufgaben" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Dateiname" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Modelltyp" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Keine Gruppe" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Seiten-URL ist durch die Konfiguration gesperrt" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Neustart erforderlich" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Eine Einstellung wurde geändert, die einen Neustart des Servers erfordert" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Ausstehende Migrationen" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Anzahl der ausstehenden Datenbankmigrationen" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Name der Serverinstanz" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Kurze Beschreibung der Instanz" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Name der Instanz verwenden" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Den Namen der Instanz in der Titelleiste verwenden" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Anzeige von `Über` einschränken" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Zeige das `Über` Fenster nur Administratoren" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Firmenname" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "interner Firmenname" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Basis-URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Basis-URL für dieses Instanz" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Standardwährung" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Wählen Sie die Basiswährung für Preisberechnungen aus" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Verfügbare Währungen" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Liste der unterstützten Währungskürzel" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Währungsaktualisierungsintervall" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "Tage" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Währungs-Aktualisierungs-Plugin" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Zu verwendendes Währungs-Aktualisierungs-Plugin" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Von URL herunterladen" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Herunterladen von externen Bildern und Dateien von URLs erlaubt" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Download-Größenlimit" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maximal zulässige Größe für heruntergeladene Bilder" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Benutzer-Agent zum Herunterladen von Daten" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Überschreiben des Benutzer-Agenten, der verwendet wird, um Bilder und Dateien von externer Servern herunterzuladen (leer für die Standardeinstellung)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Strenge URL-Prüfung" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Erfordert die Schema-Spezifikation bei der Validierung von URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Prüfungsintervall aktualisieren" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Wie oft soll nach Updates gesucht werden? (auf 0 setzen zum Deaktivieren)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatische Sicherung" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Automatische Sicherung der Datenbank- und Mediendateien aktivieren" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervall für automatische Sicherung" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Anzahl der Tage zwischen automatischen Sicherungen" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Aufgabenlöschinterval" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Ergebnisse der Hintergrundaufgabe werden nach der angegebenen Anzahl von Tagen gelöscht" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Löschintervall für Fehlerprotokolle" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Fehlerprotokolle werden nach der angegebenen Anzahl von Tagen gelöscht" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Löschintervall für Benachrichtigungen" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Benutzerbenachrichtigungen werden nach der angegebenen Anzahl von Tagen gelöscht" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Bacode-Feature verwenden" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Barcode-Scanner Unterstützung im Webinterface aktivieren" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Barcode-Eingabeverzögerung" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Verzögerungszeit bei Barcode-Eingabe" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Barcode Webcam-Unterstützung" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Barcode-Scannen über Webcam im Browser erlauben" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Artikelrevisionen" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Revisions-Feld für Artikel aktivieren" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Löschen aus Baugruppe erlauben" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "RegEx Muster für die Zuordnung von Teil-IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Ändern von IPN erlaubt" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Teil-Stückliste kopieren" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Teil-Parameter kopieren" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Teil-Testdaten kopieren" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kategorie-Parametervorlage kopieren" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Kategorie-Parameter Vorlagen kopieren wenn ein Teil angelegt wird" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Teile sind standardmäßig Vorlagen" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Teile können standardmäßig in Baugruppen benutzt werden" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Kaufbar" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Artikel sind grundsätzlich kaufbar" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Verkäuflich" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Artikel sind grundsätzlich verkaufbar" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Artikel sind grundsätzlich verfolgbar" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuell" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Teile sind grundsätzlich virtuell" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Verwandte Teile anzeigen" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Verwandte Teile eines Teils anzeigen" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Initialer Lagerbestand" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Initiale Lieferantendaten" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Anzeigeformat für Teilenamen" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Format für den Namen eines Teiles" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Standardsymbol der Teilkategorie" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Standardsymbol der Teilkategorie (leer bedeutet kein Symbol)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Dezimalstellen für minimalen Preis" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Dezimalstellen für maximalen Preis" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Zulieferer-Preise verwenden" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Lieferanten-Staffelpreise in die Gesamt-Preisberechnungen einbeziehen" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Kaufverlauf überschreiben" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historische Bestellungspreise überschreiben die Lieferanten-Staffelpreise" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Lagerartikel-Preis verwenden" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Lagerartikelpreis Alter" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Variantenpreise verwenden" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Variantenpreise in die Gesamt-Preisberechnungen einbeziehen" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Nur aktive Varianten" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Nur aktive Variantenteile zur Berechnung der Variantenbepreisung verwenden" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervall für Neuberechnung von Preisen" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interne Preise" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Interne Preise für Teile aktivieren" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Interne Preisüberschreibung" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "Falls verfügbar, überschreiben interne Preise Preispannenberechnungen" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Labeldruck aktivieren" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Labeldruck über die Website aktivieren" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Label Bild DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Berichte aktivieren" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Berichterstellung aktivieren" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Entwickler-Modus" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Berichte im Entwickler-Modus generieren (als HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Berichtsfehler protokollieren" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Fehler, die beim Erstellen von Berichten auftreten, protokollieren" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Seitengröße" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Standardseitenformat für PDF-Bericht" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Parameter Einheiten durchsetzen" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Global einzigartige Seriennummern" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Seriennummern für Lagerartikel müssen global eindeutig sein" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Erschöpften Lagerartikel löschen" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "Legt das Standardverhalten fest, wenn ein Lagerartikel aufgebraucht ist" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Losnummer Vorlage" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Bestands-Ablauf" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Ablaufen von Bestand ermöglichen" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Abgelaufenen Bestand verkaufen" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Verkauf von abgelaufenem Bestand erlaubt" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Bestands-Stehzeit" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Abgelaufenen Bestand verbauen" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Verbauen von abgelaufenen Bestand erlaubt" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Bestands-Eigentümerkontrolle" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Eigentümerkontrolle für Lagerorte und Teile aktivieren" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Standardsymbol für Lagerort" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Standardsymbol für Lagerstandort (leer bedeutet kein Symbol)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Zeige installierte Lagerartikel" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Anzeige der installierten Lagerartikel in Bestandstabellen" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Prüfe BOM bei der Installation von Elementen" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Erlaube Verschieben von \"nicht auf Lager\" Bestand" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Bauauftragsreferenz-Muster" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Verantwortlicher Besitzer erforderlich" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Jeder Bestellung muss ein verantwortlicher Besitzer zugewiesen werden" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blockieren bis Test bestanden" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Rücksendungen aktivieren" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Aktivieren der Rücksendung-Funktion in der Benutzeroberfläche" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Referenz Muster für Rücksendungen" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Abgeschlossene Rücksendungen bearbeiten" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "Bearbeitung von Rücksendungen nach Abschluss erlauben" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Auftragsreferenz-Muster" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Auftrag Standardsendung" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Erstelle eine Standardsendung für Aufträge" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Abgeschlossene Aufträge bearbeiten" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Versendete Bestellungen als abgeschlossen markieren" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 -msgid "Purchase Order Reference Pattern" -msgstr "Bestellungsreferenz-Muster" - -#: common/setting/system.py:889 -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:901 -msgid "Edit Completed Purchase Orders" -msgstr "Abgeschlossene Einkaufsaufträge bearbeiten" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Bestellungsreferenz-Muster" + +#: common/setting/system.py:918 +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 +msgid "Edit Completed Purchase Orders" +msgstr "Abgeschlossene Einkaufsaufträge bearbeiten" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Bestellungen automatisch abschließen" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Passwort vergessen aktivieren" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Registrierung erlauben" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSO aktivieren" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "SSO auf den Anmeldeseiten aktivieren" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "SSO Selbstregistrierung aktivieren" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "SSO Gruppensynchronisation aktivieren" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO Gruppenschlüssel" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email-Adresse erforderlich" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Benutzer müssen bei der Registrierung eine E-Mail angeben" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "SSO-Benutzer automatisch ausfüllen" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Benutzer-Details automatisch aus SSO-Konto ausfüllen" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "E-Mail zweimal" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Passwort zweimal" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "Bei der Registrierung den Benutzer zweimal nach dem Passwort fragen" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Erlaubte Domains" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Gruppe bei Registrierung" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "MFA erzwingen" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Benutzer müssen Multifaktor-Authentifizierung verwenden." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Plugins beim Start prüfen" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Nach Plugin-Aktualisierungen suchen" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Periodische Überprüfungen auf Updates für installierte Plugins aktivieren" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "URL-Integration aktivieren" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Plugins zum Hinzufügen von URLs aktivieren" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Navigations-Integration aktivieren" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Plugins zur Integration in die Navigation aktivieren" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "App-Integration aktivieren" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Plugins zum Hinzufügen von Apps aktivieren" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Terminplan-Integration aktivieren" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Geplante Aufgaben aktivieren" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Ereignis-Integration aktivieren" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Plugins ermöglichen auf interne Ereignisse zu reagieren" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Externe Standorte ausschließen" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Automatische Inventur-Periode" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Vollständige Namen von Benutzern anzeigen" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Vollständigen Namen von Benutzern anstatt Benutzername anzeigen" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Teststation-Daten aktivieren" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Teststation-Datenerfassung für Testergebnisse aktivieren" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Fehlerberichte empfangen" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Benachrichtigungen bei Systemfehlern erhalten" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Zuletzt verwendete Druckmaschinen" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Teil ist aktiv" msgid "Manufacturer is Active" msgstr "Hersteller ist aktiv" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Lieferantenteil ist aktiv" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Internes Teil ist aktiv" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Lieferant ist aktiv" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Hersteller" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Firma" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Firmen" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Firmenbeschreibung" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Firmenbeschreibung" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Webseite" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Firmenwebsite Adresse/URL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Kontakt-Tel." -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kontakt-Telefon" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontakt-Email" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Anlaufstelle" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link auf externe Firmeninformation" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Ist dieses Unternehmen aktiv?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Ist Kunde" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Verkaufen Sie Teile an diese Firma?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Ist Zulieferer" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Kaufen Sie Teile von dieser Firma?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Ist Hersteller" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Produziert diese Firma Teile?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Standard-Währung für diese Firma" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adresse" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adressen" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Firma auswählen" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Adresstitel" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Titel zur Beschreibung des Adresseintrages" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Primäre Adresse" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Als primäre Adresse festlegen" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Linie 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adresszeile 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Linie 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adresszeile 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Postleitzahl" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Stadt/Region" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Postleitzahl Stadt/Region" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Staat/Provinz" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Bundesland" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Land" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adresse Land" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Versandnotizen" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notizen für Versandkurier" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Interne Versandnotizen" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Versandnotizen für interne Verwendung" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link zu Adressinformationen (extern)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Herstellerteil" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Basisteil" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Teil auswählen" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Hersteller auswählen" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Hersteller-Teilenummer" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "Externe URL für das Herstellerteil" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Teilbeschreibung des Herstellers" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "Packeinheiten müssen mit den Basisteileinheiten kompatibel sein" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Packeinheiten müssen größer als Null sein" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Verlinktes Herstellerteil muss dasselbe Basisteil referenzieren" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Zulieferer" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Zulieferer auswählen" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Lagerbestandseinheit (SKU) des Zulieferers" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Ist dieser Lieferantenteil aktiv?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Herstellerteil auswählen" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Teil-URL des Zulieferers" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Zuliefererbeschreibung des Teils" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "Basiskosten" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Verpackungen" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Teile-Verpackungen" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Packmenge" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "Vielfache" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Mehrere bestellen" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Verfügbare Menge von Lieferanten" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Verfügbarkeit aktualisiert" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Datum des letzten Updates der Verfügbarkeitsdaten" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Standard-Währung für diesen Zulieferer" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Firmenname" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Auf Lager" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" -msgstr "" +msgstr "Feld" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" -msgstr "" +msgstr "Spalte" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Fehler" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Gültig" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Anzahl der zu druckenden Kopien für jedes Label" msgid "Connected" msgstr "Verbunden" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Unbekannt" @@ -4598,7 +4698,7 @@ msgstr "Drucken" #: machine/machine_types/label_printer.py:234 msgid "Warning" -msgstr "" +msgstr "Warnung" #: machine/machine_types/label_printer.py:235 msgid "No media" @@ -4606,7 +4706,7 @@ msgstr "Keine Medien" #: machine/machine_types/label_printer.py:236 msgid "Paper jam" -msgstr "" +msgstr "Papierstau" #: machine/machine_types/label_printer.py:237 msgid "Disconnected" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Gruppe" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Bestellreferenz" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Ausstehend" @@ -4728,7 +4828,7 @@ msgstr "Ausstehend" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Erstellt von" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Hat Preise" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Bestellung" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Bestellung abgeschlossen" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Internes Teil" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Bestellung ausstehend" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Fertig" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Bestellung" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Bestellung" msgid "Sales Order" msgstr "Auftrag" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Gesamtpreis" msgid "Total price for this order" msgstr "Gesamtpreis für diese Bestellung" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Auftragswährung" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "Währung für diesen Auftrag (leer lassen, um Firmenstandard zu verwenden)" @@ -4851,718 +4963,750 @@ msgstr "Währung für diesen Auftrag (leer lassen, um Firmenstandard zu verwende msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Kontakt stimmt nicht mit der ausgewählten Firma überein" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Auftragsbeschreibung (optional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Projektcode für diesen Auftrag auswählen" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link auf externe Seite" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Zieldatum" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Geplantes Lieferdatum für Auftrag." -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Aufgabedatum" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Datum an dem die Bestellung aufgegeben wurde" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 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:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Ansprechpartner für diesen Auftrag" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Firmenadresse für diesen Auftrag" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Bestell-Referenz" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Bestellungs-Status" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Firma bei der die Teile bestellt werden" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Zulieferer-Referenz" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Zulieferer Bestellreferenz" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "Empfangen von" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Datum an dem der Auftrag fertigstellt wurde" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Ziel-Lager" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Teile-Zulieferer muss dem Zulieferer der Bestellung entsprechen" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Position stimmt nicht mit Kaufauftrag überein" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Anzahl muss eine positive Zahl sein" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kunde" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Firma an die die Teile verkauft werden" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Kundenreferenz" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Bestellreferenz" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Versanddatum" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "Versand von" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Bestellung ist bereits abgeschlossen" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Bestellung ist bereits storniert" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Nur ein offener Auftrag kann als abgeschlossen markiert werden" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Anzahl" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Position - Referenz" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Position - Notizen" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Positionsbeschreibung (optional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Zusätzlicher Kontext für diese Zeile" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Stückpreis" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Lieferantenteil muss mit Lieferant übereinstimmen" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Zuliefererteil" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Empfangen" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Empfangene Objekt-Anzahl" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Preis" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Preis pro Einheit" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "Nur verkaufbare Teile können einem Auftrag zugewiesen werden" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Verkaufspreis" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Stückverkaufspreis" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Versendet" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Versendete Menge" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Versanddatum" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Lieferdatum" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Versanddatum" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Kontrolliert von" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Benutzer, der diese Sendung kontrolliert hat" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Sendung" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Sendungsnummer" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Sendungsverfolgungsnummer" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informationen zur Sendungsverfolgung" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Rechnungsnummer" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Referenznummer für zugehörige Rechnung" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Sendung wurde bereits versandt" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Sendung hat keine zugewiesene Lagerartikel" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Lagerartikel wurde nicht zugewiesen" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Kann Lagerartikel keiner Zeile ohne Teil hinzufügen" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Die zugeordnete Anzahl darf nicht die verfügbare Anzahl überschreiten" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Reserviermenge muss größer null sein" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Anzahl für serialisierte Lagerartikel muss 1 sein" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Auftrag gehört nicht zu Sendung" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Sendung gehört nicht zu Auftrag" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Position" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Sendungsnummer-Referenz" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Position" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Lagerartikel für Zuordnung auswählen" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Anzahl für Bestandszuordnung eingeben" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Rücksendungsreferenz" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Firma von der die Artikel zurückgeschickt werden" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Status der Rücksendung" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Artikel zur Rücksendung auswählen" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Empfangsdatum" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Ergebnis" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Ergebnis für dieses Zeilenelement" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Positionen" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Abgeschlossene Positionen" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Lieferant" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Bestellung kann nicht verworfen werden" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Erlaube das Schließen des Auftrags mit unvollständigen Positionen" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Auftrag hat unvollständige Positionen" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Der Auftrag ist nicht offen" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automatische Preisgestaltung" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Kaufpreis automatisch basierend auf Lieferantenbestandsdaten berechnen" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Kaufpreiswährung" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Elemente zusammenfügen" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Lieferanten-Teilenummer" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Interne Teilenummer" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Zuliefererteil muss ausgewählt werden" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Bestellung muss angegeben sein" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Lieferant muss mit der Bestellung übereinstimmen" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Die Bestellung muss mit dem Lieferant übereinstimmen" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Position" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Zielort für empfangene Teile auswählen" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Losnummer für eingehende Lagerartikel" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Ablaufdatum" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Seriennummern für eingehende Lagerartikel" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Barcode" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Gescannter Barcode" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Barcode ist bereits in Verwendung" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Positionen müssen angegeben werden" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Ziel-Lagerort muss angegeben werden" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Barcode muss eindeutig sein" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Abgeschlossene Sendungen" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Verkaufspreis-Währung" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Keine Sendungsdetails angegeben" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Anzahl muss positiv sein" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Seriennummern zum Zuweisen eingeben" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Sendung wurde bereits versandt" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Sendung ist nicht diesem Auftrag zugeordnet" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Folgende Serienummern konnten nicht gefunden werden" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Artikel der Bestellzeile zurücksenden" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Artikel entspricht nicht der Rücksendeschrift" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Artikel wurde bereits erhalten" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Verkaufspreis-Währung" @@ -5598,146 +5742,150 @@ msgstr "Rückerstattung" msgid "Reject" msgstr "Ablehnen" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Überfällige Bestellung" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Bestellung {po} ist jetzt überfällig" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Überfälliger Auftrag" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Auftrag {so} ist jetzt überfällig" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Markiert" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Nach markierten Kategorien filtern" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Ebenen" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filter nach Kategorietiefe" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Oberste Ebene" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Mehrstufig" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Unterkategorien in gefilterte Ergebnisse einbeziehen" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Übergeordnetes" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Nach übergeordneter Kategorie filtern" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Unterkategorien in der angegebenen Kategorie ausschließen" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Ergebnisse" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Verwendet" @@ -5746,11 +5894,11 @@ msgstr "Verwendet" msgid "Part Category" msgstr "Teil-Kategorie" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Teil-Kategorien" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Standard-Lagerort" @@ -5778,7 +5926,7 @@ msgstr "Standard-Stichworte für Teile dieser Kategorie" msgid "Icon" msgstr "Symbol" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Symbol (optional)" @@ -5799,1025 +5947,1050 @@ msgstr "Standard-Wert" msgid "Default Parameter Value" msgstr "Standard Parameter Wert" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Teile" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 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:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN muss mit Regex-Muster {pattern} übereinstimmen" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Ein Lagerartikel mit dieser Seriennummer existiert bereits" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Doppelte IPN in den Teil-Einstellungen nicht erlaubt" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Teil mit diesem Namen, IPN und Revision existiert bereits." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Strukturellen Teilekategorien können keine Teile zugewiesen werden!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Name des Teils" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Ist eine Vorlage" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Ist dieses Teil eine Vorlage?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Ist dieses Teil eine Variante eines anderen Teils?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante von" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Artikelbeschreibung (optional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Schlüsselwörter" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Teile-Kategorie" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN (Interne Produktnummer)" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Revisions- oder Versionsnummer" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Version" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" -msgstr "" +msgstr "Revision von" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Standard Ablaufzeit" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Ablauf-Zeit (in Tagen) für Bestand dieses Teils" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimaler Bestand" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimal zulässiger Bestand" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Maßeinheit für diesen Teil" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Kann dieses Teil zum Bauauftrag von anderen genutzt werden?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Kann dieses Teil an Kunden verkauft werden?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Ist dieses Teil aktiv?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Stückliste kontrolliert von" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "BOM Kontrolldatum" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Erstellungs-Nutzer" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Verantwortlicher Besitzer für dieses Teil" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Mehrere verkaufen" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Währung für die Berechnung der Preise im Cache" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimale Stücklisten Kosten" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minimale Kosten für Teile" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maximale Stücklisten Kosten" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maximale Kosten für Teile" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimale Einkaufskosten" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimale historische Kaufkosten" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maximale Einkaufskosten" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maximale historische Einkaufskosten" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimaler interner Preis" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimale Kosten basierend auf den internen Staffelpreisen" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maximaler interner Preis" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maximale Kosten basierend auf internen Preisstaffeln" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimaler Lieferantenpreis" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Mindestpreis für Teil von externen Lieferanten" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maximaler Lieferantenpreis" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maximaler Preis für Teil von externen Lieferanten" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimale Variantenkosten" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Berechnete minimale Kosten für Variantenteile" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maximale Variantenkosten" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Berechnete maximale Kosten für Variantenteile" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimale Kosten" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Mindestkosten überschreiben" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maximale Kosten" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Maximale Kosten überschreiben" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Berechnete Mindestkosten" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Berechnete Maximalkosten" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Mindestverkaufspreis" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Mindestverkaufspreis basierend auf Staffelpreisen" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maximaler Verkaufspreis" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maximalverkaufspreis basierend auf Staffelpreisen" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Mindestverkaufskosten" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimaler historischer Verkaufspreis" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maximale Verkaufskosten" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maximaler historischer Verkaufspreis" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Teil für die Inventur" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Stückzahl" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Anzahl einzelner Bestandseinträge zum Zeitpunkt der Inventur" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Insgesamt verfügbarer Lagerbestand zum Zeitpunkt der Inventur" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Datum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Datum der Inventur" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Mindestbestandswert" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Geschätzter Mindestwert des vorhandenen Bestands" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maximaler Bestandswert" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Geschätzter Maximalwert des vorhandenen Bestands" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Test-Name" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Namen für diesen Test eingeben" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Testschlüssel" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Vereinfachter Schlüssel zum Test" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Test-Beschreibung" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Beschreibung für diesen Test eingeben" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Ist dieser Test aktiviert?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Benötigt" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Muss dieser Test erfolgreich sein?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Erfordert Wert" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Anhang muss eingegeben werden" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Gültige Optionen für diesen Test (durch Komma getrennt)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Ausgangsteil auswählen" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Untergeordnetes Teil" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Diese Stücklisten-Position ist optional" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Referenz der Postion auf der Stückliste" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notizen zur Stücklisten-Position" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Prüfsumme" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "überprüft" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Diese Stücklistenposition wurde validiert" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Wird vererbt" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Menge muss eine Ganzzahl sein" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Zuliefererteil muss festgelegt sein" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Stücklisten Ersatzteile" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "Ersatzteil kann nicht identisch mit dem Hauptteil sein" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Übergeordnete Stücklisten Position" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Ersatzteil" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Teil 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Teil 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "verknüpftes Teil auswählen" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Doppelte Beziehung existiert bereits" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Übergeordnete Kategorie" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Übergeordnete Teilkategorie" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Unter-Kategorien" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Ergebnisse" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Anzahl der Ergebnisse, die in dieser Vorlage aufgezeichnet wurden" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Kaufwährung dieses Lagerartikels" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Originalteil" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Originalteil zum Duplizieren auswählen" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Bild kopieren" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Bild vom Originalteil kopieren" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Stückliste kopieren" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Stückliste vom Originalteil kopieren" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Parameter kopieren" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Parameterdaten vom Originalteil kopieren" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Anmerkungen kopieren" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Notizen aus Originalteil kopieren" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Start-Bestandsmenge" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Initialer Lagerort" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Lagerstandort für dieses Teil angeben" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Lieferant auswählen (oder leer lassen, um zu überspringen)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Hersteller auswählen (oder leer lassen, um zu überspringen)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Hersteller-Teilenummer" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Ausgewählte Firma ist kein gültiger Lieferant" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Ausgewählte Firma ist kein gültiger Hersteller" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Herstellerteil mit dieser MPN existiert bereits" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Lieferantenteil mit dieser SKU existiert bereits" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategoriename" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Im Bau" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Lagerartikel" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Gesamtbestand" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Nicht zugewiesenes Lager" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Alternatives Lager" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Teil duplizieren" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Initiale Daten von anderem Teil kopieren" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Initialer Lagerbestand" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Erstelle Teil mit Ausgangsbestand" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Lieferanteninformationen" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Lieferanteninformationen zu diesem Teil hinzufügen" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kategorieparameter kopieren" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Parametervorlagen aus der ausgewählten Teilkategorie kopieren" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Vorhandenes Bild" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Dateiname eines vorhandenen Teilbildes" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Bilddatei existiert nicht" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Gesamte Stückliste validieren" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Herstellbar" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Niedrigster Preis" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Berechneten Wert für Mindestpreis überschreiben" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Mindestpreis Währung" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Höchster Preis" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Berechneten Wert für maximalen Preis überschreiben" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Maximalpreis Währung" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Aktualisieren" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Preis für dieses Teil aktualisieren" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Mindestpreis darf nicht größer als der Maximalpreis sein" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Der Maximalpreis darf nicht kleiner als der Mindestpreis sein" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Teil auswählen, von dem Stückliste kopiert wird" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Bestehende Daten entfernen" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Bestehende Stücklisten-Positionen vor dem Kopieren entfernen" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Vererbtes einschließen" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Stücklisten-Positionen einbeziehen, die von Vorlage-Teilen geerbt werden" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Ungültige Zeilen überspringen" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Aktiviere diese Option, um ungültige Zeilen zu überspringen" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Ersatzteile kopieren" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Ersatzteile beim Duplizieren von Stücklisten-Positionen kopieren" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Benachrichtigungen über geringen Bestand" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Zugewiesene Menge" msgid "Label printing failed" msgstr "Labeldruck fehlgeschlagen" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Fehler beim Rendern des Etikett als PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Fehler beim Rendern des Etikett als HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Keine Elemente zum Drucken übergeben" @@ -7100,7 +7273,7 @@ msgstr "Bietet native Unterstützung für Barcodes" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF-Etikettendrucker" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Debug-Modus" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Debug-Modus aktivieren - gibt Roh-HTML statt PDF zurück" @@ -7500,7 +7673,7 @@ msgstr "Rand" msgid "Print a border around each label" msgstr "Einen Rahmen um jedes Label drucken" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Querformat" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Nur Mitarbeiter können Plugins verwalten" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Plugin-Installation ist deaktiviert" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin wurde erfolgreich installiert" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin installiert in {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Plugin wurde nicht in der Registry gefunden" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Plugin ist kein gepacktes Plugin" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Plugin-Paketname nicht gefunden" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Nur Mitarbeiter können Plugins verwalten" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Plugin-Deinstallation ist deaktiviert" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin kann nicht deinstalliert werden, da es momentan aktiv ist" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Plugin erfolgreich deinstallieren" @@ -7689,21 +7875,21 @@ msgstr "Paket-Plugin" msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Kein Autor gefunden" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin benötigt mindestens Version {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin benötigt maximal Version {v}" @@ -7884,55 +8070,55 @@ msgstr "Installation nicht bestätigt" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Komplett neu laden" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Führe ein vollständiges Nachladen der Plugin-Registrierung durch" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Neuladen erzwingen" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Erzwinge ein erneutes Laden der Plugin-Registrierung, auch wenn sie bereits geladen ist" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Plugins sammeln" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Plugins sammeln und zur Registrierung hinzufügen" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Plugin aktivieren" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Dieses Plugin aktivieren" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Konfiguration löschen" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Plugin-Konfiguration aus der Datenbank löschen" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Teile" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "US-Letter" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Vorlagen Name" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Beschreibung der Vorlage" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Dateinamen-Muster" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filter" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Seitengröße für PDF-Berichte" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Bericht in Querformat anzeigen" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Breite [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Label-Breite in mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Höhe [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Label-Höhe in mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Schnipsel" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Berichts-Snippet" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Snippet-Beschreibung" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Ressource" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Berichts-Ressource" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Ressource-Beschreibung" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Etiketten-Vorlage auswählen" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seriennummer" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Verbaute Objekte" @@ -8248,184 +8438,196 @@ msgstr "Kein Ergebnis (erforderlich)" msgid "No result" msgstr "Kein Ergebnis" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Die Bestandsdatei ist nicht vorhanden" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Bilddatei nicht gefunden" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image tag benötigt eine Bauteilinstanz" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image tag erfordert eine Firmeninstanz" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filtern nach Standorttiefe" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Unterorte in gefilterte Ergebnisse einbeziehen" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Übergeordneter Ort" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtern nach übergeordnetem Ort" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Statuscode" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Externer Standort" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Teile-Baum" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Gültigkeitsdauer vor" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Gültigkeitsdauer nach" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "überfällig" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Menge ist erforderlich" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Gültiges Teil muss angegeben werden" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Der angegebene Lieferantenartikel existiert nicht" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Lagerstandorte Typen" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Bestand-Lagerort" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Bestand-Lagerorte" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Besitzer" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Besitzer auswählen" @@ -8461,7 +8663,7 @@ msgstr "Besitzer auswählen" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Extern" @@ -8481,274 +8683,282 @@ msgstr "Standortart dieses Standortes" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Lagerartikel können nicht in strukturelle Lagerorte abgelegt werden!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Für virtuelle Teile können keine Lagerartikel erstellt werden" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "Anzahl muss für Objekte mit Seriennummer 1 sein" -#: stock/models.py:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Teil kann nicht zu sich selbst gehören" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Referenz verweist nicht auf das gleiche Teil" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Eltern-Lagerartikel" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Basis-Teil" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Passendes Zuliefererteil für diesen Lagerartikel auswählen" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Verpackung, in der dieser Lagerartikel gelagert ist" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "verbaut in" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Losnummer für diesen Lagerartikel" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Bestand" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Quellbau" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Bauauftrag für diesen Lagerartikel" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Verbraucht von" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Bauauftrag der diesen Lagerartikel verbrauchte" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Quelle Bestellung" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Bestellung für diesen Lagerartikel" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Ziel-Auftrag" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Löschen wenn leer" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Diesen Lagerartikel löschen wenn der Bestand aufgebraucht ist" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Preis für eine Einheit bei Einkauf" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "In Teil umgewandelt" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Teil ist nicht verfolgbar" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Anzahl stimmt nicht mit den Seriennummern überein" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Testvorlage existiert nicht" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Artikel wurde einem Kundenauftrag zugewiesen" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Lagerartikel ist in anderem Element verbaut" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Lagerartikel enthält andere Artikel" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Artikel wurde einem Kunden zugewiesen" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Lagerartikel wird aktuell produziert" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Nachverfolgbare Lagerartikel können nicht zusammengeführt werden" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Artikel duplizeren" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Lagerartikel müssen auf dasselbe Teil verweisen" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Lagerartikel müssen auf dasselbe Lieferantenteil verweisen" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Status-Codes müssen zusammenpassen" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Eintrags-Notizen" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Wert muss für diesen Test angegeben werden" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Anhang muss für diesen Test hochgeladen werden" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Testergebnis" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Test Ausgabe Wert" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Test Ergebnis Anhang" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Test Notizen" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Teststation" -#: stock/models.py:3085 +#: stock/models.py:3111 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:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Gestartet" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Der Zeitstempel des Teststarts" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Fertiggestellt" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Der Zeitstempel der Test-Beendigung" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Testvorlage für dieses Ergebnis" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "Vorlagen-ID oder Testname muss angegeben werden" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Elternposition" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Seriennummern für neue Teile eingeben" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "abgelaufen" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Untergeordnete Objekte" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Einkaufspreis dieses Lagerartikels, pro Einheit oder Verpackungseinheit" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Anzahl der zu serialisierenden Lagerartikel eingeben" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Ziel-Bestand" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Seriennummern können diesem Teil nicht zugewiesen werden" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Seriennummern existieren bereits" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Lagerartikel für Installation auswählen" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Zu installierende Menge" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Anzahl der zu verwendenden Artikel eingeben" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr " Transaktionsnotizen hinzufügen (optional)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Die zu verwendende Menge muss mindestens 1 sein" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Lagerartikel ist nicht verfügbar" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Ausgewähltes Teil ist nicht in der Stückliste" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Die zu verwendende Menge darf die verfügbare Menge nicht überschreiten" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Ziel Lagerort für unverbautes Objekt" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "Lagerartikel konnte nicht mit Zulieferteil zugewiesen werden" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Lagerartikel Status-Code" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Lagerartikel auswählen, um den Status zu ändern" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Keine Lagerartikel ausgewählt" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Unter-Lagerorte" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Übergeordneter Lagerort" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Teil muss verkaufbar sein" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Artikel ist einem Kundenauftrag zugeordnet" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Artikel ist einem Fertigungsauftrag zugeordnet" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Kunde zum Zuweisen von Lagerartikel" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Ausgewählte Firma ist kein Kunde" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Notizen zur Lagerzuordnung" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Eine Liste der Lagerbestände muss angegeben werden" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notizen zur Lagerartikelzusammenführung" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Unterschiedliche Lieferanten erlauben" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Zusammenführen von Lagerartikeln mit unterschiedlichen Lieferanten erlauben" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Unterschiedliche Status erlauben" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Zusammenführen von Lagerartikeln mit unterschiedlichen Status-Codes erlauben" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Mindestens zwei Lagerartikel müssen angegeben werden" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Keine Änderung" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Primärschlüssel Lagerelement" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Bestandsbewegungsnotizen" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Nächste Seriennummer" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Vorherige Seriennummer" @@ -9369,227 +9579,247 @@ msgstr "Das letzte Mal, wo das Token verwendet wurde" msgid "Revoked" msgstr "Widerrufen" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Berechtigung geändert" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Ansicht" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Berechtigung Einträge anzuzeigen" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Hinzufügen" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Berechtigung Einträge zu erstellen" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Ändern" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Berechtigungen Einträge zu ändern" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Löschen" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Berechtigung Einträge zu löschen" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Interne" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Gast" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Sprache" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Bevorzugte Sprache für diesen Benutzer" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Name anzeigen" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organisation" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Bestellungen" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Aufträge" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Rücksendeaufträge" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Benutzername" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Vorname" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Vorname des Benutzers" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Nachname" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Nachname des Benutzers" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "E-Mailadresse des Benutzers" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Mitarbeiter" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Hat der Benutzer die Mitarbeiter Berechtigung" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Administrator" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Ist dieser Benutzer ein Administrator" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Ist dieses Benutzerkonto aktiv" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Passwort" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Ihr Konto wurde erstellt." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Bitte benutzen Sie die Passwort-zurücksetzen-Funktion, um sich anzumelden" -#: users/serializers.py:452 +#: users/serializers.py:497 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 d830b45be2..e09355a9ea 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Το API endpoint δε βρέθηκε" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Πρέπει να παρέχεται λίστα Προϊόντων ή φίλτρων για μαζική ενέργεια" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Τα Προϊόντα πρέπει να δοθούν ως λίστα" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Η λίστα Προϊόντων που δόθηκε δεν είναι έγκυρη" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Τα φίλτρα πρέπει να δοθούν ως λεξικό" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Τα φίλτρα που δόθηκαν δεν είναι έγκυρα" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Το φίλτρο all πρέπει να χρησιμοποιείται μόνο με τιμή true" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Κανένα Aντικείμενο δεν ταιριάζει στα κριτήρια που δόθηκαν" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Δεν δόθηκαν δεδομένα" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Αυτό το πεδίο πρέπει να είναι μοναδικό." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Δεν έχετε δικαιώματα να το δείτε αυτό" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Δεν ήταν δυνατή η μετατροπή από {original} σε {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Μη έγκυρη ποσότητα" @@ -112,13 +105,13 @@ msgstr "Εισάγετε ημερομηνία" msgid "Invalid decimal value" msgstr "Μη έγκυρη δεκαδική τιμή" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Σημειώσεις" @@ -131,75 +124,91 @@ msgstr "Η τιμή '{name}' δεν εμφανίζεται σε μορφή μο msgid "Provided value does not match required pattern: " msgstr "Η παρεχόμενη τιμή δεν ταιριάζει με το απαιτούμενο απαραραίητη μοτίβο: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Δεν είναι δυνατή η σειριοποίηση περισσότερων από 1000 Προϊόντων ταυτόχρονα" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Κενό σειριακό αριθμό συμβολοσειράς" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Διπλότυπο ArialTTumblr" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Μη έγκυρη ομάδα: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Το εύρος της ομάδας {group} υπερβαίνει την επιτρεπόμενη ποσότητα ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Δεν βρέθηκαν σειριακοί αριθμοί" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Ο αριθμός μοναδικών σειριακών αριθμών ({n}) πρέπει να αντιστοιχεί στην ποσότητα ({q})" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Αφαιρέστε τα HTML tags από την τιμή που εισάγατε" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Τα δεδομένα περιέχουν απαγορευμένο περιεχόμενο markdown" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Σφάλμα σύνδεσης" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Ο διακομιστής απάντησε με μη έγκυρο κωδικό κατάστασης" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Προέκυψε σφάλμα" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Ο διακομιστής ανταποκρίθηκε με \"Invalid Content-Length value\"" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Η εικόνα είναι πολύ μεγάλη σε μέγεθος" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Η λήψη εικόνας ξεπέρασε το μέγιστο μέγεθος" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Ο διακομιστής επέστρεψε σφάλμα %1$d %2$s" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Το URL δεν είναι έγκυρο αρχείο εικόνας" @@ -207,11 +216,11 @@ msgstr "Το URL δεν είναι έγκυρο αρχείο εικόνας" msgid "Log in to the app" msgstr "Σύνδεση στην εφαρμογή" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Πρέπει να ενεργοποιήσετε τον έλεγχο ταυτότητας δύο παραγόντων πριν κάνετε οτιδήποτε άλλο." @@ -255,133 +264,108 @@ msgstr "Η αναφορά πρέπει να ταιριάζει με το απα msgid "Reference number is too large" msgstr "Ο αριθμός αναφοράς είναι πολύ μεγάλος" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Μη έγκυρη επιλογή" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Όνομα" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Περιγραφή" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Περιγραφή (προαιρετική)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Μονοπάτι" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Διπλότυπα ονόματα δεν μπορούν να υπάρχουν στον ίδιο γονέα" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Σημειώσεις Markdown (προαιρετικό)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Στοιχεία Barcode" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Δεδομένα barcode τρίτων" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash barcode" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Μοναδικό hash δεδομένων barcode" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Βρέθηκε υπάρχων barcode" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Αποτυχία εργασίας" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Η εργασία background worker '{f}' απέτυχε μετά από {n} προσπάθειες" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Σφάλμα διακομιστή" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Ένα σφάλμα έχει καταγραφεί από το διακομιστή." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Πρέπει να είναι αριθμός" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Νόμισμα" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Επιλέξτε νόμισμα από τις διαθέσιμες επιλογές" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Μη έγκυρη τιμή" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Απομακρυσμένες Εικόνες" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Διεύθυνση URL του αρχείου απομακρυσμένης εικόνας" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Η λήψη εικόνων από απομακρυσμένο URL δεν είναι ενεργοποιημένη" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Αποτυχία λήψης εικόνας από απομακρυσμένο URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Κινέζικα (απλοποιημένα)" msgid "Chinese (Traditional)" msgstr "Κινέζικα (Παραδοσιακά)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Διαθέσιμη ενημέρωση" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Μια ενημέρωση για το InvenTree είναι διαθέσιμη" @@ -553,30 +537,30 @@ msgstr "Μη έγκυρη φυσική μονάδα" msgid "Not a valid currency code" msgstr "Μη έγκυρος κωδικός συναλλάγματος" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Κατάσταση παραγγελίας" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Γονική Κατασκευή" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Συμπερίληψη παραλλαγών" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Συμπερίληψη παραλλαγών" msgid "Part" msgstr "Εξάρτημα" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Κατηγορία" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Πρόγονος κατασκευής" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Ανατεθειμένες σε εμένα" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Ανατεθεί σε" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Δημιουργήθηκε πριν από" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Δημιουργήθηκε μετά από" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Με ημερομηνία έναρξης" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Ημερομηνία έναρξης πριν από" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Ημερομηνία έναρξης μετά από" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Με ημερομηνία στόχο" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Ημερομηνία στόχος πριν από" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Ημερομηνία στόχος μετά από" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Ολοκληρώθηκε πριν από" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Ολοκληρώθηκε μετά από" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Ελάχιστη ημερομηνία" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Μέγιστη ημερομηνία" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Εξαίρεση δέντρου" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Η έκδοση πρέπει να ακυρωθεί πριν διαγραφεί" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Αναλώσιμο" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Προαιρετικό" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Συναρμολόγηση" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Υπό παρακολούθηση" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Υπό δοκιμή" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Εκκρεμής παραγγελία" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Κατανεμημένο" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Καταναλωμένο" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Σε παραγγελία" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Σειρά Κατασκευής" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Τοποθεσία" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Έξοδος" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Φιλτράρισμα με βάση το ID του αποθέματος εξόδου. Χρησιμοποιήστε 'null' για να βρείτε μη εγκατεστημένα στοιχεία κατασκευής" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Δημιουργία Παραγγελιών" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Το BOM της συναρμολόγησης δεν έχει επικυρωθεί" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Δεν μπορεί να δημιουργηθεί εντολή κατασκευής για ανενεργό Aντικειμένου" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Δεν μπορεί να δημιουργηθεί εντολή κατασκευής για μη κλειδωμένο Aντικειμένου" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Οι εντολές κατασκευής μπορούν να εκτελεστούν εξωτερικά μόνο για Προϊόντα που μπορούν να αγοραστούν" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Πρέπει να οριστεί υπεύθυνος χρήστης ή ομάδα" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Εξάρτημα από εντολή κατασκευής δεν μπορεί να αλλάξει" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Η ημερομηνία στόχος πρέπει να είναι μετά την ημερομηνία έναρξης" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Αναφορά Παραγγελίας Κατασκευής" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Αναφορά Παραγγελίας Κατασκευής" msgid "Reference" msgstr "Αναφορά" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Σύντομη περιγραφή της κατασκευής (προαιρετικό)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Επιλέξτε τμήμα για κατασκευή" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Κωδικός Παραγγελίας Πωλήσεων" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Τοποθεσία Προέλευσης" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Επιλέξτε τοποθεσία από την οποία θα γίνει απόθεμα, για αυτή την κατασκευή (αφήστε κενό για να πάρετε από οποιαδήποτε θέση αποθήκευσης)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "Εξωτερική κατασκευή" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Αυτή η εντολή κατασκευής εκτελείται εξωτερικά" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Τοποθεσία Προορισμού" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Επιλέξτε την τοποθεσία όπου θα αποθηκευτούν τα ολοκληρωμένα στοιχεία" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Ποσότητα Κατασκευής" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Αριθμός αντικειμένων για κατασκευή" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Ολοκληρωμένα αντικείμενα" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Αριθμός αντικειμένων αποθέματος που έχουν ολοκληρωθεί" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Κατάσταση Κατασκευής" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Κωδικός κατάστασης κατασκευής" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Κωδικός Παρτίδας" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Κωδικός παρτίδας για αυτήν την κατασκευή" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Ημερομηνία Δημιουργίας" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Ημερομηνία έναρξης κατασκευής" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Προγραμματισμένη ημερομηνία έναρξης για αυτή την εντολή κατασκευής" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Ημερομηνία ολοκλήρωσης στόχου" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Ημερομηνία ολοκλήρωσης της κατασκευής. Η κατασκευή θα καθυστερήσει μετά από αυτή την ημερομηνία." -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Ημερομηνία ολοκλήρωσης" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "ολοκληρώθηκε από" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Εκδόθηκε από" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Χρήστης που εξέδωσε αυτήν την παραγγελία κατασκευής" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Υπεύθυνος" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτή την εντολή κατασκευής" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Εξωτερικοί σύνδεσμοι" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Σύνδεσμος προς εξωτερική διεύθυνση URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Προτεραιότητα Κατασκευής" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Προτεραιότητα αυτής της εντολής κατασκευής" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Κωδικός Έργου" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Κωδικός έργου για αυτήν την εντολή κατασκευής" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Δεν είναι δυνατή η ολοκλήρωση της εντολής κατασκευής με ανοιχτές θυγατρικές κατασκευές" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Δεν είναι δυνατή η ολοκλήρωση της εντολής κατασκευής με μη ολοκληρωμένα προϊόντα" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "Αποτυχία εκχώρησης εργασίας για την ολοκλήρωση των κατανομών κατασκευής" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Η παραγγελία κατασκευής {build} έχει ολοκληρωθεί" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Πρέπει να δοθούν σειριακοί αριθμοί για τα ανιχνεύσιμα Προϊόντα" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Δεν καθορίστηκε έξοδος κατασκευής" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Η έξοδος κατασκευής δεν ταιριάζει με την παραγγελία κατασκευής" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Η ποσότητα πρέπει να είναι μεγαλύτερη από 0" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Η ποσότητα δεν μπορεί να είναι μεγαλύτερη από την παραγόμενη ποσότητα" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "Η έξοδος κατασκευής δεν έχει περάσει όλες τις απαιτούμενες δοκιμές" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "Δεν είναι δυνατή η μερική ολοκλήρωση προϊόντος κατασκευής με δεσμευμένα στοιχεία" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Γραμμή εντολής κατασκευής" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Αντικείμενο κατασκευής" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Ποσότητα" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Απαιτούμενη ποσότητα για την εντολή κατασκευής" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Ποσότητα καταναλωμένου αποθέματος" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Το στοιχείο κατασκευής πρέπει να ορίζει μια έξοδο κατασκευής, καθώς το κύριο τμήμα επισημαίνεται ως ανιχνεύσιμο" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Το επιλεγμένο στοιχείο αποθέματος δεν ταιριάζει με τη γραμμή ΤΥ" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Η ποσότητα πρέπει να είναι 1 για σειριακό απόθεμα" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Η καταχωρημένη ποσότητα ({q}) δεν πρέπει να υπερβαίνει τη διαθέσιμη ποσότητα αποθέματος ({a})" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Στοιχείο αποθέματος είναι υπερ-κατανεμημένο" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Στοιχείο Αποθέματος" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Στοιχείο πηγαίου αποθέματος" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Ποσότητα αποθέματος για διάθεση για κατασκευή" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Εγκατάσταση σε" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Αποθήκη προορισμού" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Επίπεδο κατασκευής" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Όνομα Προϊόντος" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Κατασκευή Εξόδου" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Η έξοδος κατασκευής δεν ταιριάζει με την παραγγελία κατασκευής" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Το εξερχόμενο μέρος δεν ταιριάζει με το μέρος BuildOrder" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Αυτή η έξοδος κατασκευής δεν έχει εκχωρηθεί πλήρως" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Εισάγετε ποσότητα για την έξοδο κατασκευής" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Ακέραιη ποσότητα που απαιτείται για ανιχνεύσιμα μέρη" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Ακέραιη ποσότητα που απαιτείται, καθώς ο λογαριασμός των υλικών περιέχει ανιχνεύσιμα μέρη" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Σειριακοί αριθμοί" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Εισάγετε ποσότητα για την έξοδο κατασκευής" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Τοποθεσία αποθέματος για την έξοδο κατασκευής" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Αυτόματη Κατανομή Σειριακών Αριθμών" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Αυτόματη κατανομή των απαιτούμενων στοιχείων με τους αντίστοιχους σειριακούς αριθμούς" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Οι παρακάτω σειριακοί αριθμοί υπάρχουν ήδη ή δεν είναι έγκυροι" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Πρέπει να παρέχεται μια λίστα με τα αποτελέσματα κατασκευής" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Θέση αποθέματος για απορριφθείσες παραγωγές" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Απόρριψη Κατανομών" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Απορρίψτε τυχόν κατανομές αποθέματος για παραγωγές που έχουν απορριφθεί" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Αιτία απόρριψης προϊόντων κατασκευής" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Τοποθεσία για ολοκληρωμένα προϊόντα κατασκευής" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Αποδοχή Ελλιπούς Δέσμευσης" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Ολοκλήρωσε τα προϊόντα εάν το απόθεμα δεν έχει δεσμευτεί πλήρως" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Κατανάλωση δεσμευμένου αποθέματος" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "Κατανάλωση οποιουδήποτε αποθέματος έχει ήδη δεσμευτεί για αυτή την κατασκευή" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Αφαίρεση Ατελείωτων Προϊόντων" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Διαγράψτε τυχόν προϊόντα κατασκευής που δεν έχουν ολοκληρωθεί" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Δεν επιτρέπεται" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Αποδοχή ως κατανάλωση για αυτή την παραγγελία κατασκευής" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Αποδέσμευση πριν από την ολοκλήρωση αυτής της παραγγελίας κατασκευής" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Υπερ-δεσμευμένο Απόθεμα" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Πώς θέλετε να χειριστείτε το επιπλέον απόθεμα που έχει δεσμευτεί στην παραγγελία κατασκευής" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Μερικά στοιχεία αποθέματος έχουν υπερ-δεσμευτεί" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Αποδοχή Μη Δεσμευμένων" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Αποδεχτείτε ότι αντικείμενα αποθέματος δεν έχουν δεσμευτεί πλήρως σε αυτή την παραγγελία κατασκευής" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Το απαιτούμενο απόθεμα δεν έχει δεσμευτεί πλήρως" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Αποδοχή Μη Ολοκληρωμένων" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "Αποδεχτείτε ότι ο απαιτούμενος αριθμός προϊόντων κατασκευής δεν έχει ολοκληρωθεί" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Ο απαιτούμενος αριθμός προϊόντων δεν έχει ολοκληρωθεί" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Η εντολή κατασκευής έχει ανοιχτές θυγατρικές εντολές κατασκευής" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Η εντολή κατασκευής πρέπει να βρίσκεται σε κατάσταση παραγωγής" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Η παραγγελία κατασκευής έχει ελλιπή προϊόντα" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Γραμμή Κατασκευής" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Προϊόν Κατασκευής" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Το προϊόν κατασκευής πρέπει να δείχνει στην ίδια κατασκευή" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Αντικείμενο Γραμμής Κατασκευής" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part πρέπει να δείχνει στο ίδιο εξάρτημα με τη εντολή κατασκευής" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Το στοιχείο πρέπει να υπάρχει στο απόθεμα" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Η διαθέσιμη ποσότητα ({q}) έχει ξεπεραστεί" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "Πρέπει να καθοριστεί έξοδος κατασκευής για την κατανομή ανιχνεύσιμων Προϊόντων" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Δεν μπορεί να καθοριστεί έξοδος κατασκευής για την κατανομή μη ανιχνεύσιμων Προϊόντων" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Πρέπει να δοθούν στοιχεία κατανομής" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Τοποθεσία αποθέματος από την οποία θα ληφθούν τα Προϊόντα (αφήστε κενό για λήψη από οποιαδήποτε τοποθεσία)" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Εξαίρεση τοποθεσίας" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Εξαιρέστε στοιχεία αποθέματος από αυτή την επιλεγμένη τοποθεσία" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Εναλλάξιμο απόθεμα" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Στοιχεία αποθέματος σε πολλές τοποθεσίες μπορούν να χρησιμοποιηθούν εναλλάξ" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Εναλλακτικό απόθεμα" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Να επιτρέπεται η κατανομή εναλλακτικών Προϊόντων" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Προαιρετικά στοιχεία" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Κατανομή προαιρετικών στοιχείων BOM στην εντολή κατασκευής" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Αποτυχία εκκίνησης εργασίας αυτόματης κατανομής" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Αναφορά BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID Προϊόντος BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Όνομα Προϊόντος BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Κατασκευή" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Aντικειμένου προμηθευτή" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Δεσμευμένη ποσότητα" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Αναφορά κατασκευής" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Όνομα κατηγορίας Προϊόντος" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Ανιχνεύσιμο" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Κληρονομημένο" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Να επιτρέπονται παραλλαγές" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Στοιχείο BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Σε παραγωγή" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Προγραμματισμένο για κατασκευή" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Εξωτερικό απόθεμα" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Διαθέσιμο απόθεμα" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Διαθέσιμο εναλλακτικό απόθεμα" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Διαθέσιμο απόθεμα παραλλαγών" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Η καταναλωμένη ποσότητα υπερβαίνει τη δεσμευμένη ποσότητα" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Προαιρετικές σημειώσεις για την κατανάλωση αποθέματος" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "Το στοιχείο κατασκευής πρέπει να αντιστοιχεί στη σωστή εντολή κατασκευής" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Διπλή κατανομή στοιχείου κατασκευής" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "Η γραμμή κατασκευής πρέπει να αντιστοιχεί στη σωστή εντολή κατασκευής" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Διπλή κατανομή γραμμής κατασκευής" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Πρέπει να δοθεί τουλάχιστον ένα στοιχείο ή μία γραμμή" @@ -1495,43 +1479,47 @@ msgstr "Σε αναμονή" msgid "Cancelled" msgstr "Ακυρώθηκε" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Ολοκληρώθηκε" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Απαιτείται απόθεμα για την εντολή κατασκευής" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Η εντολή κατασκευής {build} απαιτεί επιπλέον απόθεμα" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Εκπρόθεσμη εντολή κατασκευής" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Η εντολή κατασκευής {bo} είναι πλέον εκπρόθεσμη" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Είναι σύνδεσμος" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Είναι αρχείο" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Ο χρήστης δεν έχει δικαίωμα να διαγράψει αυτά τα συνημμένα" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Ο χρήστης δεν έχει δικαίωμα να διαγράψει αυτό το συνημμένο" @@ -1551,798 +1539,822 @@ msgstr "Δεν δόθηκαν έγκυροι κωδικοί συναλλάγμα msgid "No plugin" msgstr "Χωρίς πρόσθετο" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Ετικέτα κωδικού έργου" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Ενημερώθηκε" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Χρονική σήμανση τελευταίας ενημέρωσης" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Ενημερώθηκε από" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Χρήστης που ενημέρωσε τελευταίος αυτό το Aντικειμένου" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Μοναδικός κωδικός έργου" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Περιγραφή έργου" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτό το έργο" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Κλειδί ρυθμίσεων" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Τιμή ρυθμίσεων" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Η επιλεγμένη τιμή δεν είναι έγκυρη επιλογή" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Η τιμή πρέπει να είναι boolean" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Η τιμή πρέπει να είναι ακέραιος αριθμός" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Η τιμή πρέπει να είναι έγκυρος αριθμός" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Η τιμή δεν περνά τους ελέγχους εγκυρότητας" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Η συμβολοσειρά κλειδιού πρέπει να είναι μοναδική" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Χρήστης" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Ποσότητα κλιμακωτής τιμής" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Τιμή" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Τιμή μονάδας στη συγκεκριμένη ποσότητα" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Endpoint" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Το endpoint στο οποίο λαμβάνεται αυτό το webhook" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Όνομα για αυτό το webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Ενεργό" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Είναι αυτό το webhook ενεργό" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token πρόσβασης" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Μυστικό" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Κοινόχρηστο μυστικό για HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID μηνύματος" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Μοναδικό αναγνωριστικό για αυτό το μήνυμα" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Host από τον οποίο παραλήφθηκε αυτό το μήνυμα" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Κεφαλίδα" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Κεφαλίδα αυτού του μηνύματος" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Κείμενο" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Κείμενο αυτού του μηνύματος" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endpoint στο οποίο παραλήφθηκε αυτό το μήνυμα" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Επεξεργάστηκε" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Ολοκληρώθηκε η εργασία σε αυτό το μήνυμα;" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Τίτλος" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Σύνδεσμος" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Δημοσιεύθηκε" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Συντάκτης" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Περίληψη" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Αναγνωσμένο" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Διαβάστηκε αυτό το νέο;" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Αρχείο εικόνας" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Τύπος μοντέλου-στόχου για αυτή την εικόνα" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "ID μοντέλου-στόχου για αυτή την εικόνα" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Προσαρμοσμένη μονάδα" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Το σύμβολο μονάδας πρέπει να είναι μοναδικό" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Το όνομα μονάδας πρέπει να είναι έγκυρο αναγνωριστικό" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Όνομα μονάδας" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Σύμβολο" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Προαιρετικό σύμβολο μονάδας" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Ορισμός" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Ορισμός μονάδας" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Συνημμένο" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Το αρχείο λείπει" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Λείπει ο εξωτερικός σύνδεσμος" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Τύπος μοντέλου" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Τύπος μοντέλου-στόχου για την εικόνα" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Επιλέξτε αρχείο για επισύναψη" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Σχόλιο" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Σχόλιο συνημμένου" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Ημερομηνία μεταφόρτωσης" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Ημερομηνία μεταφόρτωσης του αρχείου" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Μέγεθος αρχείου" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Μέγεθος αρχείου σε bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Μη έγκυρος τύπος μοντέλου που ορίστηκε για το συνημμένο" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Προσαρμοσμένη κατάσταση" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Προσαρμοσμένες καταστάσεις" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Σετ κατάστασης αναφοράς" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Σετ καταστάσεων που επεκτείνεται με αυτή την προσαρμοσμένη κατάσταση" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Λογικό κλειδί" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "Λογικό κλειδί κατάστασης που είναι ισοδύναμο με αυτή την προσαρμοσμένη κατάσταση στη λογική της εφαρμογής" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Τιμή" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Αριθμητική τιμή που θα αποθηκευτεί στη βάση δεδομένων των μοντέλων" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Όνομα της κατάστασης" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Ετικέτα" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Ετικέτα που θα εμφανίζεται στο frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Χρώμα" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Χρώμα που θα εμφανίζεται στο frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Μοντέλο" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Μοντέλο με το οποίο συσχετίζεται αυτή η κατάσταση" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Πρέπει να επιλεγεί μοντέλο" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Πρέπει να επιλεγεί κλειδί" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Πρέπει να επιλεγεί λογικό κλειδί" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Το κλειδί πρέπει να είναι διαφορετικό από το λογικό κλειδί" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Πρέπει να δοθεί έγκυρη κλάση κατάστασης αναφοράς" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "Το κλειδί πρέπει να είναι διαφορετικό από τα λογικά κλειδιά της κατάστασης αναφοράς" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "Το λογικό κλειδί πρέπει να ανήκει στα λογικά κλειδιά της κατάστασης αναφοράς" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "Το όνομα πρέπει να είναι διαφορετικό από τα ονόματα της κατάστασης αναφοράς" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Λίστα επιλογών" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Λίστες επιλογών" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Όνομα της λίστας επιλογών" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Περιγραφή της λίστας επιλογών" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Κλειδωμένο" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Είναι αυτή η λίστα επιλογών κλειδωμένη;" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Μπορεί να χρησιμοποιηθεί αυτή η λίστα επιλογών;" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Πρόσθετο πηγής" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Πρόσθετο που παρέχει τη λίστα επιλογών" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Συμβολοσειρά πηγής" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Προαιρετική συμβολοσειρά που ταυτοποιεί την πηγή που χρησιμοποιείται για αυτή τη λίστα" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Προεπιλεγμένη καταχώρηση" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Προεπιλεγμένη καταχώρηση για αυτή τη λίστα επιλογών" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Δημιουργήθηκε" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Ημερομηνία και ώρα δημιουργίας της λίστας επιλογών" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Τελευταία ενημέρωση" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "Ημερομηνία και ώρα της τελευταίας ενημέρωσης της λίστας επιλογών" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Καταχώρηση λίστας επιλογών" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Καταχωρήσεις λίστας επιλογών" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Λίστα επιλογών στην οποία ανήκει αυτή η καταχώρηση" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Τιμή της καταχώρησης λίστας επιλογών" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Ετικέτα για την καταχώρηση λίστας επιλογών" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Περιγραφή της καταχώρησης λίστας επιλογών" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Είναι ενεργή αυτή η καταχώρηση λίστας επιλογών;" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Πρότυπο παραμέτρου" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Οι παράμετροι τύπου checkbox δεν μπορούν να έχουν μονάδες" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Οι παράμετροι τύπου checkbox δεν μπορούν να έχουν επιλογές" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Οι επιλογές πρέπει να είναι μοναδικές" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Το όνομα προτύπου παραμέτρου πρέπει να είναι μοναδικό" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Όνομα παραμέτρου" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Μονάδες" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Φυσικές μονάδες για αυτή την παράμετρο" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Περιγραφή παραμέτρου" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Checkbox" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Είναι αυτή η παράμετρος τύπου checkbox;" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Επιλογές" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Έγκυρες επιλογές για αυτή την παράμετρο (διαχωρισμένες με κόμμα)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Λίστα επιλογών για αυτή την παράμετρο" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Ενεργό" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Μη έγκυρη επιλογή για την τιμή παραμέτρου" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Πρότυπο" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Δεδομένα" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Τιμή παραμέτρου" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Σημείωση" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Προαιρετικό πεδίο σημείωσης" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Σάρωση barcode" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Δεδομένα barcode" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Χρήστης που σάρωσε το barcode" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Χρονική σήμανση" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Ημερομηνία και ώρα της σάρωσης barcode" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "URL endpoint που επεξεργάστηκε το barcode" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Πλαίσιο" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Δεδομένα πλαισίου για τη σάρωση barcode" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Απόκριση" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Δεδομένα απόκρισης από τη σάρωση barcode" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Αποτέλεσμα" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Ήταν επιτυχημένη η σάρωση barcode;" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Παρουσιάστηκε σφάλμα" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "Μήνυμα email" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "Μηνύματα email" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Ανακοινώθηκε" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Εστάλη" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Απέτυχε" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Παραδόθηκε" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Επιβεβαιώθηκε" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Εισερχόμενο" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Εξερχόμενο" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Χωρίς απάντηση" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Παρακολούθηση παράδοσης" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Παρακολούθηση ανάγνωσης" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Παρακολούθηση κλικ" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "Αναγνωριστικό για αυτό το μήνυμα (ενδέχεται να παρέχεται από εξωτερικό σύστημα)" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID νήματος" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Αναγνωριστικό για αυτό το νήμα μηνυμάτων (ενδέχεται να παρέχεται από εξωτερικό σύστημα)" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Νήμα" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Συνδεδεμένο νήμα για αυτό το μήνυμα" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Νήμα email" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Νήματα email" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Κλειδί" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "Μοναδικό κλειδί για αυτό το νήμα (χρησιμοποιείται για την ταυτοποίησή του)" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Μοναδικό αναγνωριστικό για αυτό το νήμα" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Ξεκίνησε εσωτερικά" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Ξεκίνησε αυτό το νήμα εσωτερικά;" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Ημερομηνία και ώρα δημιουργίας του νήματος" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Ημερομηνία και ώρα της τελευταίας ενημέρωσης του νήματος" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Είδη που παραλήφθηκαν" @@ -2392,1235 +2404,1303 @@ msgstr "Δείχνει αν η ρύθμιση παρακάμπτεται από msgid "Override" msgstr "Παράκαμψη" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Εκτελείται" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Εργασίες σε αναμονή" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Προγραμματισμένες εργασίες" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Αποτυχημένες εργασίες" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID εργασίας" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Μοναδικό ID εργασίας" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Κλείδωμα" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Χρόνος κλειδώματος" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Όνομα εργασίας" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Συνάρτηση" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Όνομα συνάρτησης" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Ορίσματα" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Ορίσματα εργασίας" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Ορίσματα λέξεων-κλειδιών" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Ορίσματα λέξεων-κλειδιών της εργασίας" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Όνομα αρχείου" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Τύπος μοντέλου" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "Ο χρήστης δεν έχει δικαίωμα να δημιουργήσει ή να επεξεργαστεί συνημμένα για αυτό το μοντέλο" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Η λίστα επιλογών είναι κλειδωμένη" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Χωρίς ομάδα" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Το URL του site είναι κλειδωμένο από τη ρύθμιση" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Απαιτείται επανεκκίνηση" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Μια ρύθμιση έχει αλλάξει και απαιτείται επανεκκίνηση του διακομιστή" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Εκκρεμείς migrations" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Αριθμός εκκρεμών μεταναστεύσεων βάσης δεδομένων" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Ενεργοί κωδικοί προειδοποίησης" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Λεξικό με τους ενεργούς κωδικούς προειδοποίησης" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID instance" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Μοναδικό αναγνωριστικό για αυτό το instance του InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Δημοσίευση ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Δημοσίευση του instance ID του διακομιστή στις πληροφορίες κατάστασης διακομιστή (χωρίς έλεγχο ταυτότητας)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Όνομα instance διακομιστή" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Περιγραφή κειμένου για το instance του διακομιστή" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Χρήση ονόματος instance" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Χρήση του ονόματος instance στη γραμμή τίτλου" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Περιορισμός εμφάνισης `about`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Εμφάνιση της λειτουργίας `about` μόνο σε superusers" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Επωνυμία εταιρείας" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Εσωτερική επωνυμία εταιρείας" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Βασικό URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Βασικό URL για το instance του διακομιστή" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Προεπιλεγμένο νόμισμα" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Επιλέξτε βασικό νόμισμα για τους υπολογισμούς τιμών" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Υποστηριζόμενα νομίσματα" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Λίστα υποστηριζόμενων κωδικών νομισμάτων" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Διάστημα ενημέρωσης νομισμάτων" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "Κάθε πότε θα ενημερώνονται οι συναλλαγματικές ισοτιμίες (0 για απενεργοποίηση)" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "ημέρες" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Πρόσθετο ενημέρωσης νομισμάτων" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Πρόσθετο ενημέρωσης νομισμάτων που θα χρησιμοποιηθεί" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Λήψη από URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Να επιτρέπεται η λήψη απομακρυσμένων εικόνων και αρχείων από εξωτερικό URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Όριο μεγέθους λήψης" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Μέγιστο επιτρεπόμενο μέγεθος λήψης για απομακρυσμένη εικόνα" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-agent που χρησιμοποιείται για λήψη από URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Να επιτρέπεται η αντικατάσταση του user-agent που χρησιμοποιείται για λήψη εικόνων και αρχείων από εξωτερικό URL (αφήστε κενό για το προεπιλεγμένο)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Αυστηρή επικύρωση URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Να απαιτείται ορισμός σχήματος κατά την επικύρωση URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Διάστημα ελέγχου ενημερώσεων" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Κάθε πότε θα γίνεται έλεγχος για ενημερώσεις (0 για απενεργοποίηση)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Αυτόματο αντίγραφο ασφαλείας" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Ενεργοποίηση αυτόματου backup της βάσης δεδομένων και των media αρχείων" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Διάστημα αυτόματου backup" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Ορίστε τον αριθμό ημερών μεταξύ των αυτόματων backup" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Διάστημα διαγραφής εργασιών" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Τα αποτελέσματα εργασιών παρασκηνίου θα διαγράφονται μετά από τον καθορισμένο αριθμό ημερών" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Διάστημα διαγραφής log σφαλμάτων" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Τα log σφαλμάτων θα διαγράφονται μετά από τον καθορισμένο αριθμό ημερών" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Διάστημα διαγραφής ειδοποιήσεων" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Οι ειδοποιήσεις χρηστών θα διαγράφονται μετά από τον καθορισμένο αριθμό ημερών" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Διάστημα διαγραφής email" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Τα μηνύματα email θα διαγράφονται μετά από τον καθορισμένο αριθμό ημερών" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Προστασία log email" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Αποτροπή διαγραφής εγγραφών log email" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Υποστήριξη barcode" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Ενεργοποίηση υποστήριξης σαρωτή barcode στο web interface" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Αποθήκευση αποτελεσμάτων barcode" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Αποθήκευση των αποτελεσμάτων σάρωσης barcode στη βάση δεδομένων" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Μέγιστος αριθμός σαρώσεων barcode" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Μέγιστος αριθμός αποτελεσμάτων σάρωσης barcode που θα αποθηκεύονται" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Καθυστέρηση εισόδου barcode" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Χρόνος καθυστέρησης επεξεργασίας εισόδου barcode" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Υποστήριξη barcode μέσω webcam" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Να επιτρέπεται σάρωση barcode μέσω webcam στο πρόγραμμα περιήγησης" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Εμφάνιση δεδομένων barcode" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Εμφάνιση των δεδομένων barcode στο πρόγραμμα περιήγησης ως κείμενο" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Πρόσθετο δημιουργίας barcode" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Πρόσθετο που θα χρησιμοποιείται για εσωτερική δημιουργία δεδομένων barcode" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Εκδόσεις Προϊόντων" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Ενεργοποίηση πεδίου έκδοσης για Aντικειμένου" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Μόνο εκδόσεις συναρμολογήσεων" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Να επιτρέπονται εκδόσεις μόνο για Προϊόντα συναρμολόγησης" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Να επιτρέπεται διαγραφή από συναρμολόγηση" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "Να επιτρέπεται η διαγραφή Προϊόντων που χρησιμοποιούνται σε συναρμολόγηση" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Πρότυπο regular expression για αντιστοίχιση IPN Προϊόντος" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Να επιτρέπονται διπλά IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Να επιτρέπεται σε πολλαπλά Προϊόντα να μοιράζονται το ίδιο IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Να επιτρέπεται η επεξεργασία IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "Να επιτρέπεται η αλλαγή της τιμής IPN κατά την επεξεργασία ενός Προϊόντος" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Αντιγραφή δεδομένων BOM Προϊόντος" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων BOM από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Αντιγραφή δεδομένων παραμέτρων Προϊόντος" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων παραμέτρων από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Αντιγραφή δεδομένων δοκιμών Προϊόντος" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων δοκιμών από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Αντιγραφή προτύπων παραμέτρων κατηγορίας" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Αντιγραφή προτύπων παραμέτρων κατηγορίας κατά τη δημιουργία Προϊόντος" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Τα Προϊόντα είναι πρότυπα από προεπιλογή" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "Τα Προϊόντα μπορούν να συναρμολογούνται από άλλα συστατικά από προεπιλογή" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Συστατικό" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Τα Προϊόντα μπορούν να χρησιμοποιούνται ως υποσυστατικά από προεπιλογή" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Αγοράσιμο" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Τα Προϊόντα είναι αγοράσιμα από προεπιλογή" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Πωλήσιμο" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Τα Προϊόντα είναι πωλήσιμα από προεπιλογή" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Τα Προϊόντα είναι ανιχνεύσιμα από προεπιλογή" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Εικονικό" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Τα Προϊόντα είναι εικονικά από προεπιλογή" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Εμφάνιση σχετικών Προϊόντων" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Εμφάνιση σχετικών Προϊόντων για ένα Aντικειμένου" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Αρχικά δεδομένα αποθέματος" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "Να επιτρέπεται η δημιουργία αρχικού αποθέματος κατά την προσθήκη νέου Προϊόντος" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Αρχικά δεδομένα προμηθευτή" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Να επιτρέπεται η δημιουργία αρχικών δεδομένων προμηθευτή κατά την προσθήκη νέου Προϊόντος" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Μορφή εμφάνισης ονόματος Προϊόντος" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Μορφή με την οποία εμφανίζεται το όνομα του Προϊόντος" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Προεπιλεγμένο εικονίδιο κατηγορίας Προϊόντος" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Προεπιλεγμένο εικονίδιο κατηγορίας Προϊόντος (κενό σημαίνει χωρίς εικονίδιο)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Ελάχιστα δεκαδικά ψηφία τιμολόγησης" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Ελάχιστος αριθμός δεκαδικών ψηφίων που θα εμφανίζονται στα δεδομένα τιμολόγησης" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Μέγιστα δεκαδικά ψηφία τιμολόγησης" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Μέγιστος αριθμός δεκαδικών ψηφίων που θα εμφανίζονται στα δεδομένα τιμολόγησης" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Χρήση τιμών προμηθευτή" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Συμπερίληψη κλιμακωτών τιμών προμηθευτή στους συνολικούς υπολογισμούς τιμών" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Υπέρβαση μέσω ιστορικού αγορών" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Οι ιστορικές τιμές εντολών αγοράς υπερισχύουν των κλιμακωτών τιμών προμηθευτή" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Χρήση τιμολόγησης στοιχείου αποθέματος" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Χρήση τιμών από χειροκίνητα καταχωρημένα δεδομένα αποθέματος για τους υπολογισμούς τιμών" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Ηλικία τιμολόγησης στοιχείου αποθέματος" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Εξαίρεση στοιχείων αποθέματος παλαιότερων από αυτόν τον αριθμό ημερών από τους υπολογισμούς τιμών" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Χρήση τιμολόγησης παραλλαγών" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Συμπερίληψη τιμών παραλλαγών στους συνολικούς υπολογισμούς τιμών" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Μόνο ενεργές παραλλαγές" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Χρήση μόνο ενεργών Προϊόντων παραλλαγών για τον υπολογισμό τιμών παραλλαγών" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Αυτόματη ενημέρωση τιμών" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "Αυτόματη ενημέρωση τιμών Προϊόντων όταν αλλάζουν τα εσωτερικά δεδομένα" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Διάστημα επαναυπολογισμού τιμών" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "Αριθμός ημερών πριν ενημερωθούν αυτόματα οι τιμές των Προϊόντων" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Εσωτερικές τιμές" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Ενεργοποίηση εσωτερικών τιμών για Προϊόντα" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Υπέρβαση μέσω εσωτερικής τιμής" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "Όταν υπάρχουν, οι εσωτερικές τιμές υπερισχύουν των υπολογισμών εύρους τιμών" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Ενεργοποίηση εκτύπωσης ετικετών" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Ενεργοποίηση εκτύπωσης ετικετών από το web interface" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI εικόνας ετικέτας" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Ανάλυση DPI κατά τη δημιουργία αρχείων εικόνας για πρόσθετα εκτύπωσης ετικετών" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Ενεργοποίηση αναφορών" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Ενεργοποίηση δημιουργίας αναφορών" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Λειτουργία αποσφαλμάτωσης" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Δημιουργία αναφορών σε λειτουργία αποσφαλμάτωσης (έξοδος HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Καταγραφή σφαλμάτων αναφορών" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Καταγραφή σφαλμάτων που προκύπτουν κατά τη δημιουργία αναφορών" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Μέγεθος σελίδας" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Προεπιλεγμένο μέγεθος σελίδας για PDF αναφορές" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Επιβολή μονάδων παραμέτρων" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "Αν δοθούν μονάδες, οι τιμές των παραμέτρων πρέπει να αντιστοιχούν στις καθορισμένες μονάδες" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Καθολικά μοναδικοί σειριακοί αριθμοί" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Οι σειριακοί αριθμοί των στοιχείων αποθέματος πρέπει να είναι καθολικά μοναδικοί" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Διαγραφή εξαντλημένου αποθέματος" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "Καθορίζει την προεπιλεγμένη συμπεριφορά όταν ένα στοιχείο αποθέματος εξαντλείται" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Πρότυπο κωδικού παρτίδας" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Πρότυπο για τη δημιουργία προεπιλεγμένων κωδικών παρτίδας για στοιχεία αποθέματος" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Λήξη αποθέματος" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Ενεργοποίηση λειτουργίας λήξης αποθέματος" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Πώληση ληγμένου αποθέματος" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Να επιτρέπεται η πώληση ληγμένου αποθέματος" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Χρόνος απαρχαίωσης αποθέματος" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "Αριθμός ημερών που τα στοιχεία αποθέματος θεωρούνται παλαιωμένα πριν λήξουν" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Κατασκευή με ληγμένο απόθεμα" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Να επιτρέπεται η κατασκευή με ληγμένο απόθεμα" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Έλεγχος ιδιοκτησίας αποθέματος" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Ενεργοποίηση ελέγχου ιδιοκτησίας σε τοποθεσίες και στοιχεία αποθέματος" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Προεπιλεγμένο εικονίδιο τοποθεσίας αποθέματος" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Προεπιλεγμένο εικονίδιο τοποθεσίας αποθέματος (κενό σημαίνει χωρίς εικονίδιο)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Εμφάνιση εγκατεστημένων στοιχείων αποθέματος" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Εμφάνιση εγκατεστημένων στοιχείων αποθέματος στους πίνακες αποθέματος" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Έλεγχος BOM κατά την εγκατάσταση στοιχείων" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Τα εγκατεστημένα στοιχεία αποθέματος πρέπει να υπάρχουν στο BOM του γονικού Προϊόντος" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Να επιτρέπεται μεταφορά εκτός αποθέματος" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Πρότυπο αναφοράς εντολής κατασκευής" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Απαιτούμενο πρότυπο για τη δημιουργία του πεδίου αναφοράς εντολής κατασκευής" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Απαίτηση ενεργού προϊόντος" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής για ανενεργά προϊόντα" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Απαίτηση κλειδωμένου προϊόντος" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής για ξεκλείδωτα προϊόντα" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Απαίτηση έγκυρης BOM" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής αν δεν έχει επικυρωθεί η BOM" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Απαίτηση κλειστών θυγατρικών εντολών" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "Αποτροπή ολοκλήρωσης εντολής παραγωγής μέχρι να κλείσουν όλες οι θυγατρικές εντολές" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Εξωτερικές εντολές παραγωγής" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Ενεργοποίηση λειτουργίας εξωτερικών εντολών παραγωγής" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Φραγή έως ότου περάσουν τα τεστ" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Αποτροπή ολοκλήρωσης εξόδων παραγωγής μέχρι να περάσουν όλα τα απαιτούμενα τεστ" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Ενεργοποίηση εντολών επιστροφής" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Ενεργοποίηση λειτουργίας εντολών επιστροφής στη διεπαφή χρήστη" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Μοτίβο αναφοράς εντολής επιστροφής" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής επιστροφής" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών επιστροφής" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "Επιτρέπει την επεξεργασία εντολών επιστροφής μετά την ολοκλήρωσή τους" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Μοτίβο αναφοράς εντολής πώλησης" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής πώλησης" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Προεπιλεγμένη αποστολή εντολής πώλησης" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Ενεργοποίηση δημιουργίας προεπιλεγμένης αποστολής με τις εντολές πώλησης" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών πώλησης" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Επιτρέπει την επεξεργασία εντολών πώλησης μετά την αποστολή ή ολοκλήρωσή τους" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Η αποστολή απαιτεί έλεγχο" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "Αποτροπή ολοκλήρωσης αποστολών μέχρι να ελεγχθούν τα είδη" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Σήμανση αποσταλμένων εντολών ως ολοκληρωμένων" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Οι εντολές πώλησης που επισημαίνονται ως αποσταλμένες ολοκληρώνονται αυτόματα, παρακάμπτοντας την κατάσταση «απεσταλμένο»" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής αγοράς" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών αγοράς" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Επιτρέπει την επεξεργασία εντολών αγοράς μετά την αποστολή ή ολοκλήρωσή τους" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Μετατροπή νομίσματος" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "Μετατροπή της αξίας είδους στο βασικό νόμισμα κατά την παραλαβή αποθέματος" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Αυτόματη ολοκλήρωση εντολών αγοράς" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Αυτόματη σήμανση εντολών αγοράς ως ολοκληρωμένων όταν έχουν παραληφθεί όλα τα είδη" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Ενεργοποίηση υπενθύμισης κωδικού" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Ενεργοποίηση λειτουργίας υπενθύμισης κωδικού στις σελίδες σύνδεσης" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Ενεργοποίηση εγγραφής" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "Ενεργοποίηση αυτοεγγραφής χρηστών στις σελίδες σύνδεσης" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Ενεργοποίηση SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Ενεργοποίηση SSO στις σελίδες σύνδεσης" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Ενεργοποίηση εγγραφής μέσω SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Ενεργοποίηση αυτοεγγραφής μέσω SSO στις σελίδες σύνδεσης" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Ενεργοποίηση συγχρονισμού ομάδων SSO" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Ενεργοποίηση συγχρονισμού ομάδων InvenTree με ομάδες από τον IdP" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Κλειδί ομάδας SSO" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Το όνομα του πεδίου ομάδων που παρέχεται από τον IdP" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Χάρτης ομάδων SSO" -#: common/setting/system.py:966 +#: 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 "Χαρτογράφηση ομάδων SSO σε τοπικές ομάδες InvenTree. Αν η ομάδα δεν υπάρχει, θα δημιουργηθεί." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Αφαίρεση ομάδων εκτός SSO" -#: common/setting/system.py:974 +#: 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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Απαίτηση email" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Απαίτηση συμπλήρωσης email κατά την εγγραφή" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Αυτόματη συμπλήρωση χρηστών SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Αυτόματη συμπλήρωση στοιχείων χρήστη από τα δεδομένα SSO" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Email δύο φορές" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "Κατά την εγγραφή ζητείται το email δύο φορές" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Κωδικός δύο φορές" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "Κατά την εγγραφή ζητείται ο κωδικός δύο φορές" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Επιτρεπόμενοι τομείς" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Περιορισμός εγγραφής σε συγκεκριμένους τομείς (χωρισμένοι με κόμμα, ξεκινούν με @)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Ομάδα κατά την εγγραφή" -#: common/setting/system.py:1014 +#: 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." msgstr "Ομάδα στην οποία εκχωρούνται οι νέοι χρήστες κατά την εγγραφή. Με ενεργό SSO sync, χρησιμοποιείται μόνο όταν δεν μπορεί να δοθεί ομάδα από τον IdP." -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Επιβολή MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Οι χρήστες πρέπει να χρησιμοποιούν πολυπαραγοντική ασφάλεια" -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Έλεγχος plugins κατά την εκκίνηση" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Έλεγχος ότι όλα τα plugins είναι εγκατεστημένα κατά την εκκίνηση – χρήσιμο σε container περιβάλλοντα" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Έλεγχος για ενημερώσεις plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Ενεργοποίηση περιοδικών ελέγχων για ενημερώσεις εγκατεστημένων plugins" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Ενεργοποίηση URL integration" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Ενεργοποίηση προσθήκης URL routes από plugins" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Ενεργοποίηση ενσωμάτωσης στην πλοήγηση" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Ενεργοποίηση ενσωμάτωσης των plugins στην πλοήγηση" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Ενεργοποίηση ενσωμάτωσης εφαρμογών" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Ενεργοποίηση προσθήκης εφαρμογών από plugins" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Ενεργοποίηση ενσωμάτωσης χρονοπρογραμματισμού" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Ενεργοποίηση εκτέλεσης χρονοπρογραμματισμένων εργασιών από plugins" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Ενεργοποίηση ενσωμάτωσης γεγονότων" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Ενεργοποίηση απόκρισης plugins σε εσωτερικά γεγονότα" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Ενεργοποίηση ενσωμάτωσης διεπαφής" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Ενεργοποίηση ενσωμάτωσης plugins στη διεπαφή χρήστη" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Ενεργοποίηση ενσωμάτωσης email" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Ενεργοποίηση επεξεργασίας εισερχόμενων/εξερχόμενων emails από plugins" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Ενεργοποίηση κωδικών έργου" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Ενεργοποίηση κωδικών έργου για την παρακολούθηση projects" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "Ενεργοποίηση καταγραφής ιστορικών επιπέδων και αξιών αποθέματος" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Εξαίρεση εξωτερικών τοποθεσιών" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Περίοδος αυτόματης απογραφής" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Εμφάνιση πλήρους ονόματος χρηστών" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Εμφάνιση του πλήρους ονόματος των χρηστών αντί για το όνομα χρήστη" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Εμφάνιση προφίλ χρηστών" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Εμφάνιση προφίλ χρηστών στη σελίδα προφίλ τους" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Ενεργοποίηση δεδομένων σταθμού δοκιμών" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Ενεργοποίηση συλλογής δεδομένων σταθμού δοκιμών για τα αποτελέσματα δοκιμών" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Ενεργοποίηση ping μηχανημάτων" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Ενεργοποίηση περιοδικού ping των καταχωρημένων μηχανημάτων για έλεγχο της κατάστασής τους" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "Ανενεργό: Η πλήρης διαδρομή κατηγορίας εμφανίζεται ως tooltip κατά το πέρασμα του δείκτη. Ενεργό: Η πλήρης διαδρομή κατηγορίας εμφανίζεται ως απλό κείμενο" #: 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Λήψη αναφορών σφαλμάτων" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Λήψη ειδοποιήσεων για σφάλματα συστήματος" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Τελευταίες χρησιμοποιημένες εκτυπωτικές μηχανές" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "Αποθήκευση των τελευταίων εκτυπωτικών μηχανών που χρησιμοποίησε ο χρήστης" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Το προϊόν είναι ενεργό" msgid "Manufacturer is Active" msgstr "Ο κατασκευαστής είναι ενεργός" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Το προϊόν προμηθευτή είναι ενεργό" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Το εσωτερικό προϊόν είναι ενεργό" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Ο προμηθευτής είναι ενεργός" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Κατασκευαστής" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Εταιρεία" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Διαθέτει απόθεμα" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Εταιρείες" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Περιγραφή εταιρείας" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Περιγραφή της εταιρείας" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Ιστότοπος" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL ιστοτόπου εταιρείας" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Τηλέφωνο" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Τηλέφωνο επικοινωνίας" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Email επικοινωνίας" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Επαφή" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Σημείο επαφής" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Σύνδεσμος σε εξωτερικές πληροφορίες εταιρείας" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Είναι αυτή η εταιρεία ενεργή;" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Είναι πελάτης" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Πουλάτε είδη σε αυτή την εταιρεία;" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Είναι προμηθευτής" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Αγοράζετε είδη από αυτή την εταιρεία;" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Είναι κατασκευαστής" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Κατασκευάζει αυτή η εταιρεία προϊόντα;" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Προεπιλεγμένο νόμισμα που χρησιμοποιείται για αυτή την εταιρεία" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "ΑΦΜ" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "ΑΦΜ εταιρείας" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Διεύθυνση" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Διευθύνσεις" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Επιλογή εταιρείας" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Τίτλος διεύθυνσης" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Τίτλος που περιγράφει την εγγραφή διεύθυνσης" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Κύρια διεύθυνση" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Ορισμός ως κύριας διεύθυνσης" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Γραμμή 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Γραμμή διεύθυνσης 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Γραμμή 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Γραμμή διεύθυνσης 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Ταχυδρομικός κώδικας" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Πόλη/Περιοχή" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Πόλη/περιοχή ταχυδρομικού κώδικα" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Πολιτεία/Επαρχία" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Πολιτεία ή επαρχία" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Χώρα" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Χώρα διεύθυνσης" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Σημειώσεις αποστολής για courier" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Σημειώσεις για την αποστολή με courier" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Εσωτερικές σημειώσεις αποστολής" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Σημειώσεις αποστολής για εσωτερική χρήση" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Σύνδεσμος σε πληροφορίες διεύθυνσης (εξωτερικό)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Προϊόν κατασκευαστή" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Βασικό προϊόν" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Επιλογή προϊόντος" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Επιλογή κατασκευαστή" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Κωδικός προϊόντος κατασκευαστή" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL εξωτερικού συνδέσμου προϊόντος κατασκευαστή" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Περιγραφή προϊόντος κατασκευαστή" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "Οι μονάδες συσκευασίας πρέπει να είναι συμβατές με τις μονάδες του βασικού προϊόντος" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Οι μονάδες συσκευασίας πρέπει να είναι μεγαλύτερες από το μηδέν" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Το συνδεδεμένο προϊόν κατασκευαστή πρέπει να αναφέρεται στο ίδιο βασικό προϊόν" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Προμηθευτής" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Επιλογή προμηθευτή" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Κωδικός αποθέματος προμηθευτή" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Είναι αυτό το προϊόν προμηθευτή ενεργό;" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Επιλογή προϊόντος κατασκευαστή" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL εξωτερικού συνδέσμου προϊόντος προμηθευτή" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Περιγραφή προϊόντος προμηθευτή" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "βασικό κόστος" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Ελάχιστη χρέωση (π.χ. χρέωση αποθήκευσης)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Συσκευασία" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Συσκευασία προϊόντος" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Ποσότητα ανά συσκευασία" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Συνολική ποσότητα που παρέχεται σε μία συσκευασία. Αφήστε κενό για μεμονωμένα είδη." -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "πολλαπλάσιο" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Πολλαπλάσιο παραγγελίας" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Ποσότητα διαθέσιμη από τον προμηθευτή" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Η διαθεσιμότητα ενημερώθηκε" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Ημερομηνία τελευταίας ενημέρωσης δεδομένων διαθεσιμότητας" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Κλιμακωτή τιμή προμηθευτή" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Προεπιλεγμένο νόμισμα που χρησιμοποιείται για αυτόν τον προμηθευτή" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Όνομα εταιρείας" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Σε απόθεμα" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Κλιμακωτές τιμές" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Προέκυψε σφάλμα κατά την εξαγωγή δεδομένων" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Υπάρχον αναγνωριστικό βάσης δεδομένων για την εγγραφή" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Η στήλη έχει ήδη αντιστοιχιστεί σε πεδίο της βάσης δεδομένων" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Το πεδίο έχει ήδη αντιστοιχιστεί σε στήλη δεδομένων" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "Η αντιστοίχιση στήλης πρέπει να συνδέεται με έγκυρη συνεδρία εισαγωγής" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Η στήλη δεν υπάρχει στο αρχείο δεδομένων" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Το πεδίο δεν υπάρχει στο μοντέλο προορισμού" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Το επιλεγμένο πεδίο είναι μόνο για ανάγνωση" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Συνεδρία εισαγωγής" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Πεδίο" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Στήλη" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Δείκτης γραμμής" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Αρχικά δεδομένα γραμμής" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Σφάλματα" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Έγκυρο" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "Απαιτείται ID για την ενημέρωση υπαρχόντων εγγραφών." -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Δεν βρέθηκε εγγραφή με το παρεχόμενο ID" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Δόθηκε μη έγκυρη μορφή ID" @@ -4588,7 +4688,7 @@ msgstr "Αριθμός αντιτύπων προς εκτύπωση για κά msgid "Connected" msgstr "Συνδεδεμένος" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Άγνωστο" @@ -4692,7 +4792,7 @@ msgstr "Κλειδί ιδιότητας" msgid "Value of the property" msgstr "Τιμή ιδιότητας" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Ομάδα" @@ -4720,7 +4820,7 @@ msgstr "Μέγιστη τιμή για τύπο προόδου, απαιτείτ msgid "Order Reference" msgstr "Αναφορά παραγγελίας" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Σε εκκρεμότητα" @@ -4728,7 +4828,7 @@ msgstr "Σε εκκρεμότητα" msgid "Has Project Code" msgstr "Έχει κωδικό έργου" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Δημιουργήθηκε από" @@ -4764,57 +4864,69 @@ msgstr "Ημερομηνία στόχος πριν" msgid "Target Date After" msgstr "Ημερομηνία στόχος μετά" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Έχει τιμολόγηση" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Ολοκληρώθηκε πριν" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Ολοκληρώθηκε μετά" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Εξωτερική εντολή παραγωγής" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Παραγγελία" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Η παραγγελία ολοκληρώθηκε" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Εσωτερικό προϊόν" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Η παραγγελία είναι σε εκκρεμότητα" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Ολοκληρώθηκε" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Έχει αποστολή" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Εντολή αγοράς" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Εντολή αγοράς" msgid "Sales Order" msgstr "Εντολές Πώλησης" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Συνολική τιμή" msgid "Total price for this order" msgstr "Συνολική τιμή για αυτή την παραγγελία" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Νόμισμα παραγγελίας" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "Νόμισμα για αυτή την παραγγελία (αφήστε κενό για χρήση της προεπιλογής εταιρείας)" @@ -4851,718 +4963,750 @@ msgstr "Νόμισμα για αυτή την παραγγελία (αφήστε msgid "This order is locked and cannot be modified" msgstr "Αυτή η παραγγελία είναι κλειδωμένη και δεν μπορεί να τροποποιηθεί" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Η επαφή δεν αντιστοιχεί στην επιλεγμένη εταιρεία" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Η ημερομηνία έναρξης πρέπει να είναι πριν από την ημερομηνία στόχο" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "Η διεύθυνση δεν αντιστοιχεί στην επιλεγμένη εταιρεία" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Περιγραφή παραγγελίας (προαιρετικά)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Επιλογή κωδικού έργου για αυτή την παραγγελία" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Σύνδεσμος σε εξωτερική σελίδα" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Ημερομηνία έναρξης" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Προγραμματισμένη ημερομηνία έναρξης για αυτή την παραγγελία" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Επιθυμητή Προθεσμία" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Αναμενόμενη ημερομηνία παράδοσης παραγγελίας. Η παραγγελία θα θεωρείται εκπρόθεσμη μετά από αυτή την ημερομηνία." -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Ημερομηνία έκδοσης" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Ημερομηνία έκδοσης της παραγγελίας" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτή την παραγγελία" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Σημείο επαφής για αυτή την παραγγελία" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Διεύθυνση εταιρείας για αυτή την παραγγελία" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Αναφορά παραγγελίας" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Κατάσταση" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Κατάσταση εντολής αγοράς" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Εταιρεία από την οποία παραγγέλνονται τα είδη" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Αναφορά προμηθευτή" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Κωδικός αναφοράς παραγγελίας προμηθευτή" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "παραλήφθηκε από" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Ημερομηνία ολοκλήρωσης της παραγγελίας" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Προορισμός" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Προορισμός για τα παραληφθέντα είδη" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Ο προμηθευτής προϊόντος πρέπει να ταιριάζει με τον προμηθευτή της εντολής αγοράς" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Η γραμμή δεν αντιστοιχεί στην εντολή αγοράς" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Στη γραμμή λείπει συνδεδεμένο προϊόν" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Η ποσότητα πρέπει να είναι θετικός αριθμός" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Πελάτης" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Εταιρεία στην οποία πωλούνται τα είδη" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Κατάσταση εντολής πώλησης" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Αναφορά πελάτη " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Κωδικός αναφοράς παραγγελίας πελάτη" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Ημερομηνία αποστολής" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "απεστάλη από" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Η παραγγελία είναι ήδη ολοκληρωμένη" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Η παραγγελία είναι ήδη ακυρωμένη" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Μόνο μια ανοικτή παραγγελία μπορεί να σημειωθεί ως ολοκληρωμένη" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες αποστολές" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες δεσμεύσεις αποθέματος" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες γραμμές" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Η παραγγελία είναι κλειδωμένη και δεν μπορεί να τροποποιηθεί" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Ποσότητα είδους" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Αναφορά γραμμής" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Σημειώσεις γραμμής" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Ημερομηνία στόχος για αυτή τη γραμμή (αφήστε κενό για χρήση της ημερομηνίας στόχου από την παραγγελία)" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Περιγραφή γραμμής (προαιρετικά)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Πρόσθετο πλαίσιο για αυτή τη γραμμή" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Τιμή μονάδας" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Γραμμή εντολής αγοράς" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Το προϊόν προμηθευτή πρέπει να ταιριάζει με τον προμηθευτή" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Η εντολή παραγωγής πρέπει να έχει σημειωθεί ως εξωτερική" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "Οι εντολές παραγωγής μπορούν να συνδεθούν μόνο με προϊόντα συναρμολόγησης" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "Το προϊόν της εντολής παραγωγής πρέπει να ταιριάζει με το προϊόν της γραμμής" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "Παραλήφθηκε" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Αριθμός ειδών που παραλήφθηκαν" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Τιμή αγοράς" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Τιμή μονάδας αγοράς" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "Εξωτερική εντολή παραγωγής που θα καλυφθεί από αυτή τη γραμμή" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Επιπλέον γραμμή εντολής αγοράς" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Γραμμή εντολής πώλησης" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "Μόνο πωλήσιμα προϊόντα μπορούν να αντιστοιχιστούν σε εντολή πώλησης" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Τιμή πώλησης" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Τιμή μονάδας πώλησης" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Αποστάλθηκε" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Ποσότητα που αποστάλθηκε" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Αποστολή εντολής πώλησης" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "Η διεύθυνση αποστολής πρέπει να αντιστοιχεί στον πελάτη" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Διεύθυνση αποστολής για αυτή την αποστολή" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Ημερομηνία αποστολής" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Ημερομηνία παράδοσης" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Ημερομηνία παράδοσης της αποστολής" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Έλεγχος από" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Χρήστης που έλεγξε αυτή την αποστολή" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Αποστολή" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Αριθμός αποστολής" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Αριθμός παρακολούθησης" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Πληροφορίες παρακολούθησης αποστολής" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Αριθμός τιμολογίου" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Αριθμός αναφοράς του σχετικού τιμολογίου" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Η αποστολή έχει ήδη σταλεί" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Η αποστολή δεν έχει δεσμευμένα είδη αποθέματος" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "Η αποστολή πρέπει να ελεγχθεί πριν μπορέσει να ολοκληρωθεί" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Επιπλέον γραμμή εντολής πώλησης" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Δέσμευση αποθέματος εντολής πώλησης" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Δεν έχει αντιστοιχιστεί είδος αποθέματος" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "Δεν είναι δυνατή η δέσμευση είδους αποθέματος σε γραμμή με διαφορετικό προϊόν" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Δεν είναι δυνατή η δέσμευση αποθέματος σε γραμμή χωρίς προϊόν" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Η ποσότητα δέσμευσης δεν μπορεί να υπερβαίνει την ποσότητα αποθέματος" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Η ποσότητα πρέπει να είναι μεγαλύτερη από 0" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Η ποσότητα πρέπει να είναι 1 για σειριοποιημένο είδος αποθέματος" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Η εντολή πώλησης δεν αντιστοιχεί στην αποστολή" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Η αποστολή δεν αντιστοιχεί στην εντολή πώλησης" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Γραμμή" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Αναφορά αποστολής εντολής πώλησης" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Είδος" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Επιλογή είδους αποθέματος προς δέσμευση" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Εισαγωγή ποσότητας δέσμευσης αποθέματος" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Αναφορά εντολής επιστροφής" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Εταιρεία από την οποία επιστρέφονται τα είδη" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Κατάσταση εντολής επιστροφής" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Γραμμή εντολής επιστροφής" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Πρέπει να καθοριστεί είδος αποθέματος" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Η ποσότητα επιστροφής υπερβαίνει την ποσότητα αποθέματος" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Η ποσότητα επιστροφής πρέπει να είναι μεγαλύτερη από το μηδέν" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Μη έγκυρη ποσότητα για σειριοποιημένο είδος αποθέματος" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Επιλογή είδους προς επιστροφή από τον πελάτη" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Ημερομηνία παραλαβής" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Έκβαση" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Έκβαση για αυτή τη γραμμή" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "Κόστος που σχετίζεται με την επιστροφή ή επισκευή για αυτή τη γραμμή" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Επιπλέον γραμμή εντολής επιστροφής" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID παραγγελίας" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID της παραγγελίας προς αντιγραφή" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Αντιγραφή γραμμών" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Αντιγραφή γραμμών από την αρχική παραγγελία" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Αντιγραφή επιπλέον γραμμών" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Αντιγραφή επιπλέον γραμμών από την αρχική παραγγελία" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "Γραμμές" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Ολοκληρωμένες γραμμές" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Αντιγραφή παραγγελίας" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Καθορίστε επιλογές για την αντιγραφή αυτής της παραγγελίας" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Μη έγκυρο ID παραγγελίας" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Όνομα προμηθευτή" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Η παραγγελία δεν μπορεί να ακυρωθεί" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Να επιτρέπεται το κλείσιμο της παραγγελίας με μη ολοκληρωμένες γραμμές" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Η παραγγελία έχει μη ολοκληρωμένες γραμμές" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Η παραγγελία δεν είναι ανοικτή" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Αυτόματη τιμολόγηση" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Αυτόματος υπολογισμός τιμής αγοράς βάσει των δεδομένων προϊόντος προμηθευτή" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Νόμισμα τιμής αγοράς" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Συγχώνευση ειδών" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Συγχώνευση ειδών με το ίδιο προϊόν, προορισμό και ημερομηνία στόχο σε μία γραμμή" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Εσωτερικός κωδικός προϊόντος" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Εσωτερική ονομασία προϊόντος" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Πρέπει να καθοριστεί προϊόν προμηθευτή" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Πρέπει να καθοριστεί εντολή αγοράς" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Ο προμηθευτής πρέπει να ταιριάζει με την εντολή αγοράς" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Η εντολή αγοράς πρέπει να ταιριάζει με τον προμηθευτή" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Γραμμή" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Επιλογή τοποθεσίας προορισμού για τα παραληφθέντα είδη" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Εισαγάγετε κωδικό παρτίδας για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Ημερομηνία λήξης" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Εισαγάγετε ημερομηνία λήξης για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Εισαγάγετε σειριακούς αριθμούς για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Παράκαμψη πληροφοριών συσκευασίας για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Πρόσθετη σημείωση για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Barcode" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Σαρωμένο barcode" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Το barcode χρησιμοποιείται ήδη" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Πρέπει να δοθούν γραμμές" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Πρέπει να καθοριστεί τοποθεσία προορισμού" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Οι δοθείσες τιμές barcode πρέπει να είναι μοναδικές" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Αποστολές" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Ολοκληρωμένες αποστολές" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Νόμισμα τιμής πώλησης" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Δεσμευμένα είδη" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Δεν δόθηκαν λεπτομέρειες αποστολής" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "Η γραμμή δεν συνδέεται με αυτή την παραγγελία" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Η ποσότητα πρέπει να είναι θετική" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Εισαγάγετε σειριακούς αριθμούς προς δέσμευση" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Η αποστολή έχει ήδη σταλεί" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Η αποστολή δεν συνδέεται με αυτή την παραγγελία" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Δεν βρέθηκε αντιστοίχιση για τους παρακάτω σειριακούς αριθμούς" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Οι παρακάτω σειριακοί αριθμοί δεν είναι διαθέσιμοι" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Γραμμή εντολής επιστροφής" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Η γραμμή δεν αντιστοιχεί στην εντολή επιστροφής" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Η γραμμή έχει ήδη παραληφθεί" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "Είδη μπορούν να παραληφθούν μόνο για παραγγελίες που είναι σε εξέλιξη" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Ποσότητα προς επιστροφή" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Νόμισμα τιμής γραμμής" @@ -5598,146 +5742,150 @@ msgstr "Επιστροφή χρημάτων" msgid "Reject" msgstr "Απόρριψη" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Εκπρόθεσμη εντολή αγοράς" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Η εντολή αγοράς {po} είναι πλέον εκπρόθεσμη" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Εκπρόθεσμη εντολή πώλησης" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Η εντολή πώλησης {so} είναι πλέον εκπρόθεσμη" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Εκπρόθεσμη εντολή επιστροφής" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Η εντολή επιστροφής {ro} είναι πλέον εκπρόθεσμη" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Με αστέρι" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Φιλτράρισμα κατά κατηγορίες με αστέρι" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Βάθος" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Φιλτράρισμα κατά βάθος κατηγορίας" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Ανώτατο επίπεδο" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Φιλτράρισμα κατά κατηγορίες ανώτατου επιπέδου" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Κατά κληρονομικότητα" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Συμπερίληψη υποκατηγοριών στα φιλτραρισμένα αποτελέσματα" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Γονική" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Φιλτράρισμα κατά γονική κατηγορία" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Εξαίρεση υποκατηγοριών κάτω από την καθορισμένη κατηγορία" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Έχει αποτελέσματα" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Είναι παραλλαγή" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Είναι αναθεώρηση" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Έχει αναθεωρήσεις" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Έγκυρο BOM" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Κατηγορίες κατά κληρονομικότητα" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "Αν είναι αληθές, συμπεριλαμβάνονται είδη σε θυγατρικές κατηγορίες της δοσμένης κατηγορίας" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Φιλτράρισμα κατά αριθμητικό ID κατηγορίας ή τη λέξη 'null'" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Το προϊόν συναρμολόγησης είναι υπό δοκιμή" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Το προϊόν Προϊόντος είναι υπό δοκιμή" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Χρήσεις" @@ -5746,11 +5894,11 @@ msgstr "Χρήσεις" msgid "Part Category" msgstr "Κατηγορία προϊόντος" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Κατηγορίες προϊόντων" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Προεπιλεγμένη τοποθεσία" @@ -5778,7 +5926,7 @@ msgstr "Προεπιλεγμένες λέξεις-κλειδιά για προϊ msgid "Icon" msgstr "Εικονίδιο" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Εικονίδιο (προαιρετικό)" @@ -5799,1025 +5947,1050 @@ msgstr "Προεπιλεγμένη τιμή" msgid "Default Parameter Value" msgstr "Προεπιλεγμένη τιμή παραμέτρου" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Προϊόντα" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή είναι κλειδωμένο" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή είναι ακόμη ενεργό" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή χρησιμοποιείται σε συναρμολόγηση" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Το προϊόν '{self}' δεν μπορεί να χρησιμοποιηθεί στο BOM για '{parent}' (αναδρομικά)" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Το προϊόν '{parent}' χρησιμοποιείται στο BOM για '{self}' (αναδρομικά)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "Το IPN πρέπει να ταιριάζει με το πρότυπο regex {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Το προϊόν δεν μπορεί να είναι αναθεώρηση του εαυτού του" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Δεν μπορεί να γίνει αναθεώρηση προϊόντος που είναι ήδη αναθεώρηση" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Πρέπει να καθοριστεί κωδικός αναθεώρησης" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Οι αναθεωρήσεις επιτρέπονται μόνο για προϊόντα συναρμολόγησης" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Δεν μπορεί να γίνει αναθεώρηση προϊόντος προτύπου" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Το γονικό προϊόν πρέπει να αντιστοιχεί στο ίδιο πρότυπο" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Υπάρχει ήδη είδος αποθέματος με αυτόν τον σειριακό αριθμό" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Δεν επιτρέπεται διπλό IPN στις ρυθμίσεις προϊόντος" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Υπάρχει ήδη διπλή αναθεώρηση προϊόντος." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Υπάρχει ήδη προϊόν με αυτό το όνομα, IPN και αναθεώρηση." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Τα προϊόντα δεν μπορούν να αντιστοιχιστούν σε δομικές κατηγορίες προϊόντων!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Όνομα προϊόντος" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Είναι πρότυπο" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Είναι αυτό το προϊόν προϊόν προτύπου;" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Είναι αυτό το προϊόν παραλλαγή άλλου προϊόντος;" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Παραλλαγή του" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Περιγραφή προϊόντος (προαιρετικά)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Λέξεις-κλειδιά" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Λέξεις-κλειδιά προϊόντος για βελτίωση της ορατότητας στα αποτελέσματα αναζήτησης" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Κατηγορία προϊόντος" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Αριθμός αναθεώρησης ή έκδοσης προϊόντος" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Αναθεώρηση" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Είναι αυτό το προϊόν αναθεώρηση άλλου προϊόντος;" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Αναθεώρηση του" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Πού αποθηκεύεται συνήθως αυτό το είδος;" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Προεπιλεγμένη λήξη" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Χρόνος λήξης (σε ημέρες) για είδη αποθέματος αυτού του προϊόντος" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Ελάχιστο απόθεμα" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Ελάχιστο επιτρεπτό επίπεδο αποθέματος" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Μονάδες μέτρησης για αυτό το προϊόν" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Μπορεί αυτό το προϊόν να κατασκευαστεί από άλλα προϊόντα;" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Μπορεί αυτό το προϊόν να χρησιμοποιηθεί για την κατασκευή άλλων προϊόντων;" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Έχει αυτό το προϊόν ιχνηλάτηση για μοναδικά είδη;" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Μπορούν να καταχωρηθούν αποτελέσματα δοκιμών για αυτό το προϊόν;" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Μπορεί αυτό το προϊόν να αγοραστεί από εξωτερικούς προμηθευτές;" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Μπορεί αυτό το προϊόν να πωληθεί σε πελάτες;" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Είναι αυτό το προϊόν ενεργό;" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Κλειδωμένα προϊόντα δεν μπορούν να τροποποιηθούν" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "Είναι αυτό ένα εικονικό προϊόν, όπως προϊόν λογισμικού ή άδεια;" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Το BOM έχει επικυρωθεί" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Είναι το BOM για αυτό το προϊόν έγκυρο;" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Άθροισμα ελέγχου BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Αποθηκευμένο άθροισμα ελέγχου BOM" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Έλεγχος BOM από" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Ημερομηνία ελέγχου BOM" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Χρήστης δημιουργίας" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Ιδιοκτήτης υπεύθυνος για αυτό το προϊόν" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Πώληση πολλαπλάσιων" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Νόμισμα που χρησιμοποιείται για την προσωρινή αποθήκευση υπολογισμών τιμολόγησης" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Ελάχιστο κόστος BOM" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Ελάχιστο κόστος προϊόντων Προϊόντων" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Μέγιστο κόστος BOM" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Μέγιστο κόστος προϊόντων Προϊόντων" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Ελάχιστο κόστος αγοράς" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Ελάχιστο ιστορικό κόστος αγοράς" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Μέγιστο κόστος αγοράς" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Μέγιστο ιστορικό κόστος αγοράς" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Ελάχιστη εσωτερική τιμή" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Ελάχιστο κόστος βάσει εσωτερικών κλιμακωτών τιμών" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Μέγιστη εσωτερική τιμή" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Μέγιστο κόστος βάσει εσωτερικών κλιμακωτών τιμών" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Ελάχιστη τιμή προμηθευτή" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Ελάχιστη τιμή προϊόντος από εξωτερικούς προμηθευτές" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Μέγιστη τιμή προμηθευτή" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Μέγιστη τιμή προϊόντος από εξωτερικούς προμηθευτές" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Ελάχιστο κόστος παραλλαγής" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Υπολογισμένο ελάχιστο κόστος προϊόντων παραλλαγών" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Μέγιστο κόστος παραλλαγής" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Υπολογισμένο μέγιστο κόστος προϊόντων παραλλαγών" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Ελάχιστο κόστος" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Παράκαμψη ελάχιστου κόστους" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Μέγιστο κόστος" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Παράκαμψη μέγιστου κόστους" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Υπολογισμένο συνολικό ελάχιστο κόστος" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Υπολογισμένο συνολικό μέγιστο κόστος" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Ελάχιστη τιμή πώλησης" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Ελάχιστη τιμή πώλησης βάσει κλιμακωτών τιμών" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Μέγιστη τιμή πώλησης" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Μέγιστη τιμή πώλησης βάσει κλιμακωτών τιμών" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Ελάχιστο κόστος πώλησης" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Ελάχιστη ιστορική τιμή πώλησης" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Μέγιστο κόστος πώλησης" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Μέγιστη ιστορική τιμή πώλησης" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Προϊόν για απογραφή" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Αριθμός ειδών" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Αριθμός μεμονωμένων εγγραφών αποθέματος κατά τον χρόνο απογραφής" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Συνολικό διαθέσιμο απόθεμα κατά τον χρόνο απογραφής" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Ημερομηνία" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Ημερομηνία που πραγματοποιήθηκε η απογραφή" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Ελάχιστο κόστος αποθέματος" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Εκτιμώμενο ελάχιστο κόστος αποθέματος σε διαθεσιμότητα" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Μέγιστο κόστος αποθέματος" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Εκτιμώμενο μέγιστο κόστος αποθέματος σε διαθεσιμότητα" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Κλιμακωτή τιμή πώλησης προϊόντος" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Πρότυπο δοκιμής προϊόντος" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Μη έγκυρο όνομα προτύπου - πρέπει να περιλαμβάνει τουλάχιστον έναν αλφαριθμητικό χαρακτήρα" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Πρότυπα δοκιμών μπορούν να δημιουργηθούν μόνο για προϊόντα που είναι υπό δοκιμή" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "Υπάρχει ήδη πρότυπο δοκιμής με το ίδιο κλειδί για το προϊόν" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Όνομα δοκιμής" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Εισαγάγετε όνομα για τη δοκιμή" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Κλειδί δοκιμής" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Απλοποιημένο κλειδί για τη δοκιμή" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Περιγραφή δοκιμής" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Εισαγάγετε περιγραφή για αυτή τη δοκιμή" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Είναι αυτή η δοκιμή ενεργή;" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Απαραίτητη" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Απαιτείται η επιτυχής ολοκλήρωση αυτής της δοκιμής;" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Απαιτεί τιμή" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "Απαιτεί αυτή η δοκιμή τιμή κατά την προσθήκη αποτελέσματος δοκιμής;" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Απαιτεί συνημμένο" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "Απαιτεί αυτή η δοκιμή συνημμένο αρχείο κατά την προσθήκη αποτελέσματος δοκιμής;" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Έγκυρες επιλογές για αυτή τη δοκιμή (διαχωρισμένες με κόμμα)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "Το στοιχείο BOM δεν μπορεί να τροποποιηθεί - η συναρμολόγηση είναι κλειδωμένη" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Το στοιχείο BOM δεν μπορεί να τροποποιηθεί - η συναρμολόγηση παραλλαγής είναι κλειδωμένη" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Επιλέξτε γονικό προϊόν" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Υποπροϊόν" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Επιλέξτε προϊόν που θα χρησιμοποιηθεί στο BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Ποσότητα BOM για αυτό το στοιχείο BOM" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Αυτό το στοιχείο BOM είναι προαιρετικό" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Αυτό το στοιχείο BOM είναι αναλώσιμο (δεν παρακολουθείται στις εντολές παραγωγής)" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Ποσότητα ρύθμισης" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Επιπλέον απαιτούμενη ποσότητα για μια παραγωγή, για να ληφθούν υπόψη οι απώλειες ρύθμισης" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Φθορά" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Εκτιμώμενη φθορά για μια παραγωγή, εκφρασμένη ως ποσοστό (0-100)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Πολλαπλάσιο στρογγυλοποίησης" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Στρογγυλοποίηση προς τα πάνω της απαιτούμενης ποσότητας παραγωγής στο πλησιέστερο πολλαπλάσιο αυτής της τιμής" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Αναφορά στοιχείου BOM" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Σημειώσεις στοιχείου BOM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Άθροισμα ελέγχου" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Άθροισμα ελέγχου γραμμής BOM" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Επικυρωμένο" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Αυτό το στοιχείο BOM έχει επικυρωθεί" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Κληρονομείται" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Αυτό το στοιχείο BOM κληρονομείται από τα BOM για προϊόντα παραλλαγών" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Είδη αποθέματος για προϊόντα παραλλαγών μπορούν να χρησιμοποιηθούν για αυτό το στοιχείο BOM" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Η ποσότητα πρέπει να είναι ακέραια τιμή για προϊόντα με ιχνηλάτηση" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Πρέπει να καθοριστεί υποπροϊόν" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Εναλλακτικό στοιχείο BOM" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "Το εναλλακτικό προϊόν δεν μπορεί να είναι το ίδιο με το κύριο προϊόν" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Γονικό στοιχείο BOM" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Εναλλακτικό προϊόν" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Προϊόν 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Προϊόν 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Επιλέξτε σχετικό προϊόν" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Σημείωση για αυτή τη σχέση" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "Δεν μπορεί να δημιουργηθεί σχέση προϊόντος μεταξύ ενός προϊόντος και του εαυτού του" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Υπάρχει ήδη διπλή σχέση" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Γονική κατηγορία" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Γονική κατηγορία προϊόντος" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Υποκατηγορίες" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Αποτελέσματα" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Αριθμός αποτελεσμάτων που έχουν καταγραφεί για αυτό το πρότυπο" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Νόμισμα αγοράς για αυτό το είδος αποθέματος" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Το αρχείο δεν είναι εικόνα" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Αρχικό προϊόν" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Επιλέξτε αρχικό προϊόν για αντιγραφή" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Αντιγραφή εικόνας" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Αντιγραφή εικόνας από το αρχικό προϊόν" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Αντιγραφή BOM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Αντιγραφή λίστας υλικών (BOM) από το αρχικό προϊόν" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Αντιγραφή παραμέτρων" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Αντιγραφή δεδομένων παραμέτρων από το αρχικό προϊόν" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Αντιγραφή σημειώσεων" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Αντιγραφή σημειώσεων από το αρχικό προϊόν" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Αντιγραφή δοκιμών" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "Αντιγραφή προτύπων δοκιμών από το αρχικό προϊόν" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Αρχική ποσότητα αποθέματος" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Καθορίστε αρχική ποσότητα αποθέματος για αυτό το προϊόν. Αν η ποσότητα είναι μηδέν, δεν προστίθεται απόθεμα" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Αρχική τοποθεσία αποθέματος" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Καθορίστε αρχική τοποθεσία αποθέματος για αυτό το προϊόν" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Επιλέξτε προμηθευτή (ή αφήστε κενό για παράλειψη)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Επιλέξτε κατασκευαστή (ή αφήστε κενό για παράλειψη)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Κωδικός προϊόντος κατασκευαστή" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Η επιλεγμένη εταιρεία δεν είναι έγκυρος προμηθευτής" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Η επιλεγμένη εταιρεία δεν είναι έγκυρος κατασκευαστής" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Υπάρχει ήδη προϊόν κατασκευαστή με αυτό το MPN" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Υπάρχει ήδη προϊόν προμηθευτή με αυτό το SKU" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Όνομα κατηγορίας" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Σε παραγωγή" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Ποσότητα αυτού του προϊόντος που βρίσκεται αυτή τη στιγμή σε παραγωγή" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Εκκρεμής ποσότητα αυτού του προϊόντος που έχει προγραμματιστεί για παραγωγή" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Είδη αποθέματος" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Αναθεωρήσεις" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Συνολικό απόθεμα" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Μη δεσμευμένο απόθεμα" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Απόθεμα παραλλαγών" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Αντιγραφή προϊόντος" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Αντιγραφή αρχικών δεδομένων από άλλο προϊόν" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Αρχικό απόθεμα" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Δημιουργία προϊόντος με αρχική ποσότητα αποθέματος" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Πληροφορίες προμηθευτή" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Προσθήκη αρχικών πληροφοριών προμηθευτή για αυτό το προϊόν" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Αντιγραφή παραμέτρων κατηγορίας" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Αντιγραφή προτύπων παραμέτρων από την επιλεγμένη κατηγορία προϊόντος" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Υπάρχουσα εικόνα" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Όνομα αρχείου υπάρχουσας εικόνας προϊόντος" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Το αρχείο εικόνας δεν υπάρχει" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Επικύρωση ολόκληρης της λίστας υλικών (BOM)" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Μπορεί να παραχθεί" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Απαιτείται για εντολές παραγωγής" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Δεσμευμένο σε εντολές παραγωγής" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Απαιτείται για εντολές πώλησης" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Δεσμευμένο σε εντολές πώλησης" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Ελάχιστη τιμή" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Παράκαμψη υπολογισμένης τιμής για την ελάχιστη τιμή" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Νόμισμα ελάχιστης τιμής" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Μέγιστη τιμή" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Παράκαμψη υπολογισμένης τιμής για τη μέγιστη τιμή" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Νόμισμα μέγιστης τιμής" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Ενημέρωση" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Ενημέρωση τιμολόγησης για αυτό το προϊόν" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Δεν ήταν δυνατή η μετατροπή από τα δοθέντα νομίσματα σε {default_currency}" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Η ελάχιστη τιμή δεν πρέπει να είναι μεγαλύτερη από τη μέγιστη τιμή" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Η μέγιστη τιμή δεν πρέπει να είναι μικρότερη από την ελάχιστη τιμή" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Επιλέξτε τη γονική συναρμολόγηση" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Επιλέξτε το προϊόν Προϊόντος" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Επιλέξτε προϊόν από το οποίο θα αντιγραφεί το BOM" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Αφαίρεση υπαρχόντων δεδομένων" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Αφαίρεση υπαρχόντων στοιχείων BOM πριν την αντιγραφή" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Συμπερίληψη κληρονομημένων" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Συμπερίληψη στοιχείων BOM που κληρονομούνται από προϊόντα προτύπων" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Παράλειψη μη έγκυρων γραμμών" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Ενεργοποιήστε αυτή την επιλογή για να παραλείπονται οι μη έγκυρες γραμμές" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Αντιγραφή εναλλακτικών προϊόντων" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Αντιγραφή εναλλακτικών προϊόντων κατά την αντιγραφή στοιχείων BOM" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Ειδοποίηση χαμηλού αποθέματος" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Το διαθέσιμο απόθεμα για το {part.name} έχει πέσει κάτω από το καθορισμένο ελάχιστο επίπεδο" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Ειδοποίηση παλαιού αποθέματος" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "Έχετε 1 είδος αποθέματος που πλησιάζει την ημερομηνία λήξης του" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "Έχετε {item_count} είδη αποθέματος που πλησιάζουν την ημερομηνία λήξης τους" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Χωρίς ημερομηνία λήξης" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "Έληξε πριν από {abs(days_diff)} ημέρες" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Λήγει σήμερα" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} ημέρες" @@ -7031,15 +7204,15 @@ msgstr "Ποσότητα προς δέσμευση" msgid "Label printing failed" msgstr "Η εκτύπωση ετικέτας απέτυχε" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Σφάλμα κατά τη μετατροπή της ετικέτας σε PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Σφάλμα κατά τη μετατροπή της ετικέτας σε HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Δεν δόθηκαν είδη για εκτύπωση" @@ -7100,7 +7273,7 @@ msgstr "Παρέχει εγγενή υποστήριξη για barcodes" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Ειδοποίηση αλλαγής προϊόντος" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "Το προϊόν `{part.name}` ενεργοποίησε ένα συμβάν `{part_action}`" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Εκτυπωτής ετικετών PDF InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Παρέχει εγγενή υποστήριξη για εκτύπωση ετικετών PDF" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Λειτουργία αποσφαλμάτωσης" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Ενεργοποίηση λειτουργίας αποσφαλμάτωσης - επιστρέφει ακατέργαστο HTML αντί για PDF" @@ -7500,7 +7673,7 @@ msgstr "Περίγραμμα" msgid "Print a border around each label" msgstr "Εκτύπωση περιγράμματος γύρω από κάθε ετικέτα" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Οριζόντιος προσανατολισμός" @@ -7580,64 +7753,77 @@ msgstr "Παρέχει υποστήριξη για σάρωση barcodes TME" msgid "The Supplier which acts as 'TME'" msgstr "Ο προμηθευτής που λειτουργεί ως 'TME'" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "Μόνο οι χρήστες προσωπικού μπορούν να διαχειρίζονται πρόσθετα" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Η εγκατάσταση πρόσθετων είναι απενεργοποιημένη" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Το πρόσθετο εγκαταστάθηκε με επιτυχία" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Το πρόσθετο εγκαταστάθηκε στο {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Το πρόσθετο δεν βρέθηκε στο μητρώο" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Το πρόσθετο δεν είναι πακεταρισμένο πρόσθετο" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Δεν βρέθηκε όνομα πακέτου πρόσθετου" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Μόνο οι χρήστες προσωπικού μπορούν να διαχειρίζονται πρόσθετα" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Η απεγκατάσταση προσθέτων είναι απενεργοποιημένη" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι αυτή τη στιγμή ενεργό" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι υποχρεωτικό" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι δείγμα πρόσθετου" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι ενσωματωμένο πρόσθετο" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Το πρόσθετο δεν είναι εγκατεστημένο" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Η εγκατάσταση του πρόσθετου δεν βρέθηκε" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Το πρόσθετο απεγκαταστάθηκε με επιτυχία" @@ -7689,21 +7875,21 @@ msgstr "Πρόσθετο πακέτου" msgid "Plugin" msgstr "Πρόσθετο" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Δεν βρέθηκε δημιουργός" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Το πρόσθετο '{p}' δεν είναι συμβατό με την τρέχουσα έκδοση InvenTree {v}" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Το πρόσθετο απαιτεί τουλάχιστον την έκδοση {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Το πρόσθετο απαιτεί το πολύ την έκδοση {v}" @@ -7884,55 +8070,55 @@ msgstr "Η εγκατάσταση δεν επιβεβαιώθηκε" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Πλήρης επαναφόρτωση" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Εκτέλεση πλήρους επαναφόρτωσης του μητρώου προσθέτων" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Εξαναγκασμένη επαναφόρτωση" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Εξαναγκασμένη επαναφόρτωση του μητρώου προσθέτων, ακόμη κι αν είναι ήδη φορτωμένο" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Συλλογή προσθέτων" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Συλλογή προσθέτων και προσθήκη τους στο μητρώο" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Ενεργοποίηση πρόσθετου" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Ενεργοποίηση αυτού του πρόσθετου" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Υποχρεωτικό πρόσθετο δεν μπορεί να απενεργοποιηθεί" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Διαγραφή ρύθμισης" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Διαγραφή της ρύθμισης του πρόσθετου από τη βάση δεδομένων" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "Ο χρήστης στον οποίο εφαρμόζεται αυτή η ρύθμιση" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Είδη" @@ -7948,7 +8134,7 @@ msgstr "Το πρόσθετο δεν υποστηρίζει εκτύπωση ε msgid "Invalid label dimensions" msgstr "Μη έγκυρες διαστάσεις ετικέτας" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Δεν δόθηκαν έγκυρα είδη στο πρότυπο" @@ -7972,152 +8158,156 @@ msgstr "Letter" msgid "Template file with this name already exists" msgstr "Υπάρχει ήδη αρχείο προτύπου με αυτό το όνομα" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Όνομα προτύπου" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Περιγραφή προτύπου" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Αριθμός αναθεώρησης (αυτόματη αύξηση)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Συσχέτιση με μοντέλο κατά την εκτύπωση" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Αποθήκευση του παραγόμενου αναφοράς ως συνημμένου στην συνδεδεμένη εγγραφή μοντέλου κατά την εκτύπωση" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Μοτίβο ονόματος αρχείου" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Μοτίβο για τη δημιουργία ονομάτων αρχείων" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Το πρότυπο είναι ενεργό" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Τύπος μοντέλου-στόχου για το πρότυπο" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Φίλτρα" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Φίλτρα ερωτημάτων προτύπου (λίστα ζευγών key=value χωρισμένων με κόμμα)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Αρχείο προτύπου" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Μέγεθος σελίδας για αναφορές PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Απόδοση αναφοράς σε οριζόντιο προσανατολισμό" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Συγχώνευση" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Απόδοση μίας ενιαίας αναφοράς για τα επιλεγμένα είδη" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Αναφορά που δημιουργήθηκε από το πρότυπο {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Σφάλμα σύνταξης προτύπου" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Σφάλμα κατά την απόδοση της αναφοράς" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Σφάλμα κατά τη δημιουργία της αναφοράς" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Σφάλμα κατά τη συγχώνευση των αποτελεσμάτων αναφοράς" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Πλάτος [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Πλάτος ετικέτας, σε mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Ύψος [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Ύψος ετικέτας, σε mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Σφάλμα κατά την εκτύπωση ετικετών" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Απόσπασμα" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Αρχείο αποσπάσματος αναφοράς" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Περιγραφή αρχείου αποσπάσματος" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Πόρος" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Αρχείο πόρου αναφοράς" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Περιγραφή αρχείου πόρου" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Επιλέξτε πρότυπο αναφοράς" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "Λίστα από πρωτεύοντα κλειδιά ειδών που θα συμπεριληφθούν στην αναφορά" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Επιλέξτε πρότυπο ετικέτας" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Πρόσθετο εκτύπωσης" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Επιλέξτε πρόσθετο που θα χρησιμοποιηθεί για την εκτύπωση ετικετών" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Σειριακός αριθμός" @@ -8215,7 +8405,7 @@ msgstr "Αναφορά δοκιμών είδους αποθέματος" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Εγκατεστημένα είδη" @@ -8248,184 +8438,196 @@ msgstr "Χωρίς αποτέλεσμα (υποχρεωτικό)" msgid "No result" msgstr "Χωρίς αποτέλεσμα" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Το αρχείο πόρου δεν υπάρχει" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Το αρχείο εικόνας δεν βρέθηκε" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "Το tag part_image απαιτεί μία παρουσία Aντικειμένου" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "Το tag company_image απαιτεί ένα Aντικειμένου Company" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Φιλτράρισμα ανά βάθος τοποθεσίας" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Φιλτράρισμα κατά τοποθεσίες ανώτατου επιπέδου" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Συμπερίληψη υποτοποθεσιών στα φιλτραρισμένα αποτελέσματα" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Γονική τοποθεσία" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Φιλτράρισμα βάσει γονικής τοποθεσίας" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Όνομα προϊόντος (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Το όνομα προϊόντος περιέχει (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Όνομα προϊόντος (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "IPN προϊόντος (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Το IPN προϊόντος περιέχει (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "IPN προϊόντος (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Ελάχιστο απόθεμα" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Μέγιστο απόθεμα" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Κωδικός κατάστασης" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Εξωτερική τοποθεσία" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Αναλωμένο από εντολή παραγωγής" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Εγκατεστημένο σε άλλο είδος αποθέματος" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Δέντρο προϊόντος" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Ενημερώθηκε πριν από" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Ενημερώθηκε μετά από" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Απογραφή πριν από" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Απογραφή μετά από" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Ημερομηνία λήξης πριν από" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Ημερομηνία λήξης μετά από" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Παλαιωμένο" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "Δώστε ένα PK είδους αποθέματος για να εξαιρεθεί αυτό και όλοι οι απόγονοί του" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "Διαδοχικές τοποθεσίες" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "Αν είναι true, περιλαμβάνει είδη σε θυγατρικές τοποθεσίες της δεδομένης τοποθεσίας" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Φιλτράρισμα κατά αριθμητικό ID τοποθεσίας ή τη λέξη 'null'" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Απαιτείται ποσότητα" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Πρέπει να δοθεί έγκυρο προϊόν" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Το δοθέν προϊόν προμηθευτή δεν υπάρχει" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Το προϊόν προμηθευτή έχει ορισμένο μέγεθος συσκευασίας, αλλά η σημαία use_pack_size δεν έχει τεθεί" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Δεν μπορούν να δοθούν σειριακοί αριθμοί για μη ιχνηλάσιμο προϊόν" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "Συμπερίληψη εγκατεστημένων" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Αν είναι true, περιλαμβάνει αποτελέσματα δοκιμών για είδη που είναι εγκατεστημένα κάτω από το συγκεκριμένο είδος αποθέματος" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "Φιλτράρισμα κατά αριθμητικό ID είδους αποθέματος" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Είδος αποθέματος με ID {id} δεν υπάρχει" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Τύποι τοποθεσίας αποθέματος" msgid "Default icon for all locations that have no icon set (optional)" msgstr "Προεπιλεγμένο εικονίδιο για όλες τις τοποθεσίες που δεν έχουν ορισμένο εικονίδιο (προαιρετικό)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Τοποθεσία αποθέματος" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Τοποθεσίες αποθέματος" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Ιδιοκτήτης" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Επιλέξτε ιδιοκτήτη" @@ -8461,7 +8663,7 @@ msgstr "Επιλέξτε ιδιοκτήτη" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Εξωτερικό" @@ -8481,274 +8683,282 @@ msgstr "Ο τύπος τοποθεσίας αποθέματος για αυτή msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Δεν μπορείτε να κάνετε αυτή την τοποθεσία αποθέματος δομική, επειδή κάποια είδη αποθέματος είναι ήδη τοποθετημένα σε αυτή!" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "Το {field} δεν υπάρχει" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Πρέπει να καθοριστεί προϊόν" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Τα είδη αποθέματος δεν μπορούν να τοποθετηθούν σε δομικές τοποθεσίες αποθέματος!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Δεν μπορεί να δημιουργηθεί είδος αποθέματος για εικονικά προϊόντα" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Ο τύπος προϊόντος ('{self.supplier_part.part}') πρέπει να είναι {self.part}" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "Η ποσότητα πρέπει να είναι 1 για είδος με σειριακό αριθμό" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Δεν μπορεί να οριστεί σειριακός αριθμός αν η ποσότητα είναι μεγαλύτερη από 1" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Το είδος δεν μπορεί να ανήκει στον εαυτό του" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "Το είδος πρέπει να έχει αναφορά παραγωγής αν is_building=True" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Η αναφορά παραγωγής δεν αντιστοιχεί στο ίδιο προϊόν" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Γονικό είδος αποθέματος" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Βασικό προϊόν" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Επιλέξτε αντίστοιχο προϊόν προμηθευτή για αυτό το είδος αποθέματος" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Πού βρίσκεται αυτό το είδος αποθέματος;" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Συσκευασία στην οποία αποθηκεύεται αυτό το είδος αποθέματος" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Εγκατεστημένο σε" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Είναι αυτό το είδος εγκατεστημένο σε άλλο είδος;" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Σειριακός αριθμός για αυτό το είδος" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Κωδικός παρτίδας για αυτό το είδος αποθέματος" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Ποσότητα αποθέματος" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Πηγή παραγωγής" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Εντολή παραγωγής για αυτό το είδος αποθέματος" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Έχει αναλωθεί από" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Εντολή παραγωγής που κατανάλωσε αυτό το είδος αποθέματος" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Πηγή εντολής αγοράς" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Εντολή αγοράς για αυτό το είδος αποθέματος" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Εντολή πώλησης προορισμού" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Ημερομηνία λήξης για το είδος αποθέματος. Το απόθεμα θα θεωρείται ληγμένο μετά από αυτή την ημερομηνία" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Διαγραφή κατά την εξάντληση" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Διαγραφή αυτού του είδους αποθέματος όταν εξαντληθεί" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Τιμή αγοράς ανά μονάδα κατά τον χρόνο αγοράς" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Μετατράπηκε σε προϊόν" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "Η ποσότητα υπερβαίνει το διαθέσιμο απόθεμα" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Το προϊόν δεν έχει οριστεί ως ιχνηλάσιμο" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Η ποσότητα πρέπει να είναι ακέραιος αριθμός" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Η ποσότητα δεν πρέπει να υπερβαίνει το διαθέσιμο απόθεμα ({self.quantity})" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Οι σειριακοί αριθμοί πρέπει να δοθούν ως λίστα" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Η ποσότητα δεν αντιστοιχεί στους σειριακούς αριθμούς" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Το πρότυπο δοκιμής δεν υπάρχει" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Το είδος αποθέματος έχει αντιστοιχιστεί σε εντολή πώλησης" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Το είδος αποθέματος είναι εγκατεστημένο σε άλλο είδος" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Το είδος αποθέματος περιέχει άλλα είδη" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Το είδος αποθέματος έχει αντιστοιχιστεί σε πελάτη" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Το είδος αποθέματος βρίσκεται αυτή τη στιγμή σε παραγωγή" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Σειριακό απόθεμα δεν μπορεί να συγχωνευθεί" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Διπλότυπα είδη αποθέματος" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Τα είδη αποθέματος πρέπει να αναφέρονται στο ίδιο προϊόν" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Τα είδη αποθέματος πρέπει να αναφέρονται στο ίδιο προϊόν προμηθευτή" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Οι κωδικοί κατάστασης αποθέματος πρέπει να ταιριάζουν" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "Το StockItem δεν μπορεί να μετακινηθεί καθώς δεν βρίσκεται σε απόθεμα" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Ιχνηλάτηση είδους αποθέματος" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Σημειώσεις καταχώρησης" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Αποτέλεσμα δοκιμής είδους αποθέματος" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Πρέπει να δοθεί τιμή για αυτή τη δοκιμή" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Πρέπει να μεταφορτωθεί συνημμένο για αυτή τη δοκιμή" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Μη έγκυρη τιμή για αυτή τη δοκιμή" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Αποτέλεσμα δοκιμής" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Τιμή αποτελέσματος δοκιμής" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Συνημμένο αποτελέσματος δοκιμής" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Σημειώσεις δοκιμής" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Σταθμός δοκιμής" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "Ο αναγνωριστικός κωδικός του σταθμού δοκιμής όπου πραγματοποιήθηκε η δοκιμή" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Έναρξη" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Χρονική σήμανση έναρξης της δοκιμής" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Ολοκλήρωση" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Χρονική σήμανση λήξης της δοκιμής" @@ -8792,246 +9002,246 @@ msgstr "Επιλέξτε προϊόν για το οποίο θα δημιουρ msgid "Quantity of serial numbers to generate" msgstr "Ποσότητα σειριακών αριθμών προς δημιουργία" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Πρότυπο δοκιμής για αυτό το αποτέλεσμα" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "Δεν βρέθηκε αντίστοιχη δοκιμή για αυτό το προϊόν" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "Πρέπει να δοθεί Template ID ή όνομα δοκιμής" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "Η ώρα λήξης της δοκιμής δεν μπορεί να είναι προγενέστερη της ώρας έναρξης" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Γονικό είδος" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Γονικό είδος αποθέματος" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Χρήση μεγέθους συσκευασίας κατά την προσθήκη: η καθορισμένη ποσότητα είναι ο αριθμός των συσκευασιών" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "Χρήση μεγέθους συσκευασίας" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Εισαγάγετε σειριακούς αριθμούς για νέα είδη" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Κωδικός προϊόντος προμηθευτή" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Ληγμένο" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Θυγατρικά είδη" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Εγγραφές ιχνηλάτησης" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Τιμή αγοράς αυτού του είδους αποθέματος, ανά μονάδα ή συσκευασία" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Εισαγάγετε τον αριθμό ειδών αποθέματος για σειριοποίηση" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "Δεν δόθηκε είδος αποθέματος" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Η ποσότητα δεν πρέπει να υπερβαίνει το διαθέσιμο απόθεμα ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Τοποθεσία προορισμού αποθέματος" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Δεν μπορούν να εκχωρηθούν σειριακοί αριθμοί σε αυτό το προϊόν" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Οι σειριακοί αριθμοί υπάρχουν ήδη" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Επιλέξτε είδος αποθέματος προς εγκατάσταση" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Ποσότητα προς εγκατάσταση" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Εισαγάγετε την ποσότητα των ειδών προς εγκατάσταση" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Προσθέστε σημείωση συναλλαγής (προαιρετικά)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Η ποσότητα προς εγκατάσταση πρέπει να είναι τουλάχιστον 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Το είδος αποθέματος δεν είναι διαθέσιμο" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Το επιλεγμένο προϊόν δεν βρίσκεται στο Δελτίο Υλικών (BOM)" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Η ποσότητα προς εγκατάσταση δεν πρέπει να υπερβαίνει τη διαθέσιμη ποσότητα" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Τοποθεσία προορισμού για το απεγκατεστημένο είδος" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Επιλέξτε προϊόν στο οποίο θα μετατραπεί το είδος αποθέματος" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "Το επιλεγμένο προϊόν δεν είναι έγκυρη επιλογή για μετατροπή" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "Δεν είναι δυνατή η μετατροπή είδους αποθέματος με εκχωρημένο SupplierPart" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Κωδικός κατάστασης είδους αποθέματος" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Επιλέξτε είδη αποθέματος για αλλαγή κατάστασης" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Δεν επιλέχθηκαν είδη αποθέματος" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Υποτοποθεσίες" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Γονική τοποθεσία αποθέματος" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Το προϊόν πρέπει να είναι διαθέσιμο για πώληση" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Το είδος έχει δεσμευτεί σε εντολή πώλησης" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Το είδος έχει δεσμευτεί σε εντολή παραγωγής" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Πελάτης στον οποίο θα αποδοθούν τα είδη αποθέματος" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Η επιλεγμένη εταιρεία δεν είναι πελάτης" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Σημειώσεις απόδοσης αποθέματος" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Πρέπει να δοθεί λίστα ειδών αποθέματος" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Σημειώσεις συγχώνευσης αποθέματος" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Να επιτρέπονται διαφορετικοί προμηθευτές" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Να επιτρέπεται η συγχώνευση ειδών αποθέματος με διαφορετικά προϊόντα προμηθευτή" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Να επιτρέπεται διαφορετική κατάσταση" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Να επιτρέπεται η συγχώνευση ειδών αποθέματος με διαφορετικούς κωδικούς κατάστασης" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Πρέπει να δοθούν τουλάχιστον δύο είδη αποθέματος" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Καμία αλλαγή" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Τιμή πρωτεύοντος κλειδιού StockItem" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Το είδος δεν βρίσκεται σε απόθεμα" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "Το είδος βρίσκεται ήδη σε απόθεμα" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "Η ποσότητα δεν πρέπει να είναι αρνητική" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Σημειώσεις συναλλαγής αποθέματος" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "Συγχώνευση με υπάρχον απόθεμα" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "Συγχώνευση επιστρεφόμενων ειδών με υπάρχοντα είδη αποθέματος, όπου είναι δυνατό" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Επόμενος σειριακός αριθμός" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Προηγούμενος σειριακός αριθμός" @@ -9369,227 +9579,247 @@ msgstr "Τελευταία φορά που χρησιμοποιήθηκε το msgid "Revoked" msgstr "Έχει ανακληθεί" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Σύνολο δικαιωμάτων" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Προβολή" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Δικαίωμα προβολής Προϊόντων" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Προσθήκη" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Δικαίωμα προσθήκης Προϊόντων" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Τροποποίηση" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Δικαίωμα επεξεργασίας Προϊόντων" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Διαγραφή" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Δικαίωμα διαγραφής Προϊόντων" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Bot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Εσωτερικός" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Επισκέπτης" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Γλώσσα" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Προτιμώμενη γλώσσα χρήστη" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Θέμα" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Ρυθμίσεις για το web UI σε μορφή JSON - μην τις επεξεργάζεστε χειροκίνητα!" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "Μικροεφαρμογές" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Ρυθμίσεις για τα widgets του πίνακα ελέγχου σε μορφή JSON - μην τις επεξεργάζεστε χειροκίνητα!" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Προβαλλόμενο όνομα" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Επιλεγμένο προβαλλόμενο όνομα χρήστη" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Θέση" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Κύριος επαγγελματικός τίτλος ή θέση" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Μήνυμα κατάστασης χρήστη" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Πληροφορίες τοποθεσίας χρήστη" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "Ο χρήστης χρησιμοποιεί ενεργά το σύστημα" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Προτιμώμενα στοιχεία επικοινωνίας χρήστη" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Τύπος χρήστη" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Τι τύπος χρήστη είναι;" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Οργανισμός" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Κύριος οργανισμός/φορέας του χρήστη" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Κύρια ομάδα" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Κύρια ομάδα του χρήστη" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Διαχειριστής" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Εντολές Αγοράς" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Εντολές Πώλησης" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Εντολές Επιστροφής" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Όνομα χρήστη" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Όνομα" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Το όνομα του χρήστη" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Επώνυμο" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Το επώνυμο του χρήστη" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Διεύθυνση email του χρήστη" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Προσωπικό" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Διαθέτει ο χρήστης δικαιώματα προσωπικού;" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Υπερχρήστης" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Είναι ο χρήστης υπερχρήστης;" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Είναι ο λογαριασμός χρήστη ενεργός;" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Μόνο υπερχρήστης μπορεί να τροποποιήσει αυτό το πεδίο" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Κωδικός πρόσβασης" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Κωδικός πρόσβασης του χρήστη" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Παράβλεψη προειδοποίησης" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Παράβλεψη της προειδοποίησης σχετικά με τους κανόνες κωδικού πρόσβασης" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Δεν έχετε δικαίωμα δημιουργίας χρηστών" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Ο λογαριασμός σας δημιουργήθηκε." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Παρακαλούμε χρησιμοποιήστε τη λειτουργία επαναφοράς κωδικού πρόσβασης για να συνδεθείτε" -#: users/serializers.py:452 +#: users/serializers.py:497 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 ae45204f8c..08d5437435 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-02-22 20:20+0000\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,43 +22,35 @@ msgstr "" msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "" @@ -97,7 +89,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "" @@ -113,13 +106,13 @@ msgstr "" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "" @@ -132,75 +125,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -208,11 +217,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -256,133 +265,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -538,11 +522,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -554,30 +538,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -586,9 +570,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -597,193 +581,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -791,234 +779,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1030,449 +1018,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1496,43 +1480,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1552,798 +1540,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2365,7 +2377,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2393,1235 +2405,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3906,21 +3986,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3966,365 +4062,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4429,67 +4529,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4589,7 +4689,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4693,7 +4793,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4721,7 +4821,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4729,7 +4829,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4765,57 +4865,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4823,8 +4935,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4840,11 +4952,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4852,718 +4964,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5599,146 +5743,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5747,11 +5895,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5779,7 +5927,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5800,1025 +5948,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7032,15 +7205,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7101,7 +7274,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7447,20 +7620,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7501,7 +7674,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7581,64 +7754,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7690,21 +7876,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7885,55 +8071,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7949,7 +8135,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7973,152 +8159,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8191,7 +8381,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8216,7 +8406,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8249,184 +8439,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8442,19 +8644,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8462,7 +8664,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8482,274 +8684,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8793,246 +9003,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9370,226 +9580,246 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 53bc09c89f..e84d13b24b 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "endpoint API no encontrado" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Lista de artículos o filtros deben ser proporcionados para la operación en bloque" +#: InvenTree/api.py:438 +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:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Los artículos deben ser proporcionados como una lista" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Lista de artículos no válida" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Los filtros deben ser introducidos como un diccionario" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtros proporcionados inválidos" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Todos los filtros tienen que ser usados con verdadero" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Ningún artículo coincide con el criterio proporcionado" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Sin datos proporcionados" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." -msgstr "" +msgstr "Este campo debe ser único." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "El usuario no tiene permiso para ver este modelo" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" @@ -112,13 +105,13 @@ msgstr "Ingrese la fecha" msgid "Invalid decimal value" msgstr "Número decimal no válido" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notas" @@ -131,75 +124,91 @@ msgstr "El valor '{name}' no aparece en formato de patrón" msgid "Provided value does not match required pattern: " msgstr "El valor proporcionado no coincide con el patrón requerido: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 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:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "No se ha proporcionado un número de serie" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Serie duplicada" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grupo no válido {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Numeros de serie no encontrados" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Eliminar etiquetas HTML de este valor" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Los datos contienen contenido de marcado prohibido" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "URL no válida: falta el nombre de host" + +#: InvenTree/helpers_model.py:114 +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 +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 +msgid "Too many redirects" +msgstr "Demasiadas redirecciones" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Error de conexión" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "El servidor respondió con código de estado no válido" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Se ha producido una excepción" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "El tamaño de la imagen es demasiado grande" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "La descarga de imagen excedió el tamaño máximo" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "El servidor remoto devolvió una respuesta vacía" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "La URL proporcionada no es un archivo de imagen válido" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Correo electrónico" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Debe habilitar la autenticación de doble factor antes de continuar." @@ -255,133 +264,108 @@ msgstr "La referencia debe coincidir con la expresión regular {pattern}" msgid "Reference number is too large" msgstr "El número de referencia es demasiado grande" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Selección no válida" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nombre" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descripción" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descripción (opcional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Ruta" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Los nombres duplicados no pueden existir bajo el mismo padre" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notas de Markdown (opcional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Datos de código de barras" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Datos de código de barras de terceros" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash del Código de barras" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash único de datos de código de barras" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Fallo en la tarea" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "La tarea en segundo plano '{f}' falló después de {n} intentos" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Error de servidor" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Se ha registrado un error por el servidor." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Debe ser un número válido" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Moneda" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Seleccionar moneda de las opciones disponibles" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Imagen remota" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL de imagen remota" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "La descarga de imágenes desde la URL remota no está habilitada" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Error al descargar la imagen desde la URL remota" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Chino (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chino (Tradicional)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Actualización disponible" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Una actualización para InvenTree está disponible" @@ -553,30 +537,30 @@ msgstr "Unidad física inválida" msgid "Not a valid currency code" msgstr "No es un código de moneda válido" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Estado del pedido" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Construcción o Armado Superior" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Incluye Variantes" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Incluye Variantes" msgid "Part" msgstr "Parte" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categoría" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Asignado a mí" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Asignadas a" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Creado antes" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Creado despues" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Tiene fecha inicial" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Fecha de inicio anterior" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Fecha de inicio después" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Tiene fecha límite" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Fecha objetivo antes" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Fecha objetivo después" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Completado antes" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Completado después" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Fecha Mínima" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Fecha Máxima" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Excluir Árbol" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "La compilación debe cancelarse antes de poder ser eliminada" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumible" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montaje" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Comprobable" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Pedido pendiente" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Asignadas" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Agotado" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "En pedido" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Construir órden" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Ubicación" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Salida" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Construir órdenes" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "BOM de ensamblado no ha sido validado" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Se debe especificar un usuario o grupo responsable" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "La parte del pedido de construcción no puede ser modificada" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "La fecha límite debe ser posterior a la fecha de inicio" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Número de orden de construcción o armado" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Número de orden de construcción o armado" msgid "Reference" msgstr "Referencia" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Breve descripción de la construcción (opcional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Seleccionar parte a construir o armar" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referencia de orden de venta" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Ubicación de la fuente" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Ubicación de destino" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Cantidad a crear" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Número de objetos existentes a construir" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Elementos completados" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Número de productos en stock que se han completado" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Estado de la construcción" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Código de estado de construcción" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Numero de lote" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Número de lote de este producto final" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Fecha de Creación" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Crear fecha de inicio" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Fecha de inicio programada para este pedido" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Fecha límite de finalización" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Fecha de finalización" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "terminado por" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "El usuario que emitió esta orden" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Usuario o grupo responsable de esta orden de construcción" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Link externo" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Enlace a URL externa" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Prioridad de construcción" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioridad de esta orden de construcción" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Código del proyecto" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Código de proyecto para esta orden de ensamble" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "El pedido {build} ha sido procesado" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Pedido #[order] ha sido procesado" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "No se ha especificado salida de construcción" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "La construcción de la salida ya está completa" -#: build/models.py:1019 +#: build/models.py:1030 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:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "La cantidad debe ser mayor que cero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "La cantidad no puede ser mayor que la cantidad de salida" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Construir línea de pedido" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Ensamblar equipo" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Cantidad" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Cantidad requerida para orden de ensamble" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "La cantidad debe ser 1 para el stock serializado" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Artículo de stock sobreasignado" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Artículo de stock" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Producto original de stock" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Cantidad de stock a asignar para construir" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Instalar en" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Artículo de stock de destino" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Nivel de construcción" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nombre de parte" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Esta salida de construcción ya ha sido completada" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Esta salida de construcción no está completamente asignada" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Ingrese la cantidad para la producción de la construcción" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Cantidad entera requerida para partes rastreables" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Números de serie" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Introduzca los números de serie de salidas de construcción" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Ubicación de stock para objetos construidos" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Autoasignar Números de Serie" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Debe proporcionarse una lista de salidas de construcción" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Ubicación de almacén para salidas descartadas" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Descartar asignaciones" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar cualquier asignación de existencias para las salidas descartadas" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Razón para descartar la salida de ensamble(s)" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Ubicación para las salidas de construcción completadas" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Aceptar Asignación Incompleta" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Completar salidas si el inventario no se ha asignado completamente" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consumir Stock Asignado" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Eliminar salidas incompletas" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "No permitido" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Aceptar como consumido por este pedido de construcción" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Liberar antes de completar esta orden de construcción" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Stock sobreasignado" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Algunos artículos de inventario han sido sobreasignados" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Aceptar no asignado" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "El stock requerido no ha sido completamente asignado" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Aceptar incompleto" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "La cantidad de construcción requerida aún no se ha completado" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "La orden de construcción tiene órdenes hijas de construcción abiertas" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Orden de construcción debe estar en estado de producción" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "El orden de construcción tiene salidas incompletas" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linea de ensamble" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:879 +#: build/serializers.py:885 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:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Crear partida" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "El artículo debe estar en stock" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Cantidad disponible ({q}) excedida" -#: build/serializers.py:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Debe proporcionarse la adjudicación de artículos" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Excluir ubicación" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Excluir artículos de stock de esta ubicación seleccionada" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Stock intercambiable" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Sustituir stock" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Permitir la asignación de partes sustitutas" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Elementos opcionales" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Asignar artículos de la BOM opcionales para construir la orden" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Error al iniciar la tarea de asignación automática" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Referencia BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID de la parte BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nombre de parte la BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Parte del proveedor" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Cantidad Asignada" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Referencia de orden de Ensamblado" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Nombre de la categoría por pieza" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Rastreable" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Heredado" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Item de Lista de Materiales" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "En producción" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Stock externo" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Stock Disponible" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Stock sustituto disponible" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Stock variable disponible" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "En espera" msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Terminado" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Stock requerido para la orden de construcción" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Orden de construcción atrasada" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "El pedido de construcción {bo} está atrasado" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "¿Es enlace?" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "¿Es archivo?" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "El usuario no tiene permiso para eliminar estos adjuntos" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "El usuario no tiene permiso para eliminar este adjunto" @@ -1551,798 +1539,822 @@ msgstr "No se han proporcionado códigos de divisa válidos" msgid "No plugin" msgstr "Sin plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Etiqueta del código del proyecto" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Actualizado" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Fecha y hora de la última actualización" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Código único del proyecto" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Descripción del proyecto" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Usuario o grupo responsable de este projecto" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Tecla de ajustes" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valor de ajuste" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "El valor debe ser un valor booleano" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "El valor debe ser un entero" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "El valor debe ser un número válido" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "El valor no pasa las comprobaciones de validación" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Cadena de clave debe ser única" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Usuario" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Cantidad de salto de precio" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Precio" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Precio unitario a la cantidad especificada" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Endpoint" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nombre para este webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Activo" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Está activo este webhook" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token para el acceso" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Clave" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Secreto compartido para HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID de mensaje" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identificador único para este mensaje" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Servidor" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Servidor desde el cual se recibió este mensaje" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Encabezado" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Encabezado del mensaje" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Cuerpo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Cuerpo de este mensaje" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endpoint en el que se recibió este mensaje" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Trabajado en" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "¿El trabajo en este mensaje ha terminado?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Título" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Enlace" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publicado" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Resumen" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Leer" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "¿Esta noticia ya fue leída?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Archivo de imagen" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Unidad personalizada" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "El símbolo de la unidad debe ser único" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Nombre de unidad debe ser un identificador válido" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nombre de unidad" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Símbolo de unidad opcional" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definición" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definición de unidad" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Archivo adjunto" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Archivo no encontrado" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Falta enlace externo" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Seleccionar archivo para adjuntar" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Comentario" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Comentario de archivo adjunto" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Fecha de carga" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Fecha de carga del archivo" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Tamaño del archivo" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Tamaño del archivo en bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Tipo de modelo no válido especificado para el archivo adjunto" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Llave lógica" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valor" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Nombre del estado" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que se mostrará en el frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Color" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Color que se mostrará en el frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modelo" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "El modelo debe ser seleccionado" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "La clave debe ser seleccionada" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "La clave lógica debe ser seleccionada" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Lista de selección" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Listas de Selección" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Nombre de la lista de selección" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Descripción de la lista de selección" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "¿Está bloqueada esta lista de selección?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "¿Se puede utilizar esta lista de selección?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Complemento de origen" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Complemento que proporciona la lista de selección" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Cadena de origen" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Cadena opcional que identifica la fuente usada para esta lista" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Entrada por defecto" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Entrada predeterminada para esta lista de selección" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Creado" -#: common/models.py:2296 +#: common/models.py:2378 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:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Última actualización" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Entrada de lista de selección" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Entradas de la lista de selección" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Lista de selección a la que pertenece esta entrada" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Valor del elemento de la lista de selección" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Etiqueta para la entrada de lista de selección" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Descripción de la entrada de lista de selección" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "¿Está activa esta entrada de la lista de selección?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Plantilla de parámetro" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "El nombre de parámetro en la plantilla tiene que ser único" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nombre de Parámetro" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unidades" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Casilla de verificación" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "¿Es este parámetro una casilla de verificación?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Opciones" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opciones válidas para este parámetro (separados por comas)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Lista de selección para este parámetro" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Opción inválida para el valor del parámetro" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Plantilla" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Datos" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Valor del parámetro" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Nota" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Campo de nota opcional" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Escanear código de barras" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Datos de código de barras" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Usuario que escaneó el código de barras" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Fecha y hora del escaneo de código de barras" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Dispositivo URL que procesó el código de barras" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Datos de contexto para el escaneo de código de barras" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Respuesta" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Respuesta de datos del escaneo de código de barras" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultado" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "¿El escaneo de código de barras fue exitoso?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Clave" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Artículos Recibidos" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Está en ejecución" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Tareas pendientes" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tareas Programadas" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tareas fallidas" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Identificación de Tarea" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Identificación de tarea única" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Bloquear hora" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nombre de la tarea" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Función" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nombre de la Función" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumentos de la tarea" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argumentos de palabra clave" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argumentos de palabra clave de tarea" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nombre de Archivo" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista de selección bloqueada" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Sin grupo" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "La URL del sitio está bloqueada por su configuración" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Reinicio requerido" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Se ha cambiado una configuración que requiere un reinicio del servidor" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migraciones pendientes" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Número de migraciones de base de datos pendientes" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Identificador único para esta instancia de InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nombre de la instancia del servidor" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Descriptor de cadena para la instancia del servidor" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Usar nombre de instancia" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Utilice el nombre de la instancia en la barra de título" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Restringir mostrar 'acerca de'" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Mostrar la modal `about` solo para superusuarios" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nombre de empresa" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nombre interno de empresa" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL Base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL base para la instancia del servidor" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Moneda predeterminada" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Seleccione la moneda base para los cálculos de precios" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Monedas admitidas" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Listado de códigos de divisa soportados" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervalo de actualización de moneda" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "días" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Plugin de Actualización de Moneda" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Plugin de actualización de moneda a usar" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Descargar desde URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Permitir la descarga de imágenes y archivos remotos desde la URL externa" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Límite de tamaño de descarga" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Tamaño máximo de descarga permitido para la imagen remota" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Agente de usuario usado para descargar desde la URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Permitir reemplazar el agente de usuario utilizado para descargar imágenes y archivos desde URL externa (dejar en blanco para el valor predeterminado)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validación estricta de URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Requerir especificación de esquema al validar URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Actualizar intervalo de actualización" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Con qué frecuencia comprobar actualizaciones (establecer a cero para desactivar)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Copia de seguridad automática" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Activar copia de seguridad automática de los archivos de base de datos y medios" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervalo de respaldo automático" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Especificar número de días entre eventos automatizados de copia de seguridad" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervalo de eliminación de tareas" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Los resultados de las tareas en segundo plano se eliminarán después del número especificado de días" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervalo de eliminación de registro de errores" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Los registros de errores se eliminarán después del número especificado de días" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervalo de eliminación de notificaciones" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Las notificaciones de usuario se eliminarán después del número especificado de días" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Soporte de código de barras" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Habilitar el soporte para escáner de códigos de barras en la interfaz web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Guardar resultados de código de barras" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Guardar resultados de código de barras en la base de datos" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Número máximo de escaneos de código de barras" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Número máximo de resultados de escaneo de código de barras para almacenar" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Retraso de entrada de código de barras" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tiempo de retraso en la lectura de códigos de barras" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Soporte para Webcam de código de barras" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Permitir escaneo de código de barras a través de webcam en el navegador" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Mostrar datos del código de barra como texto en el navegador" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Complemento para generar códigos de barra" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revisiones de partes" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Habilitar campo de revisión para parte" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Permitir IPN duplicado" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que varias partes compartan el mismo IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Permitir editar IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copiar parte de datos BOM" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Copiar datos BOM por defecto al duplicar una parte" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copiar parámetros de parte" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copiar parte de datos de prueba" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copiar plantillas de parámetros de categoría" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Las partes son plantillas por defecto" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Componente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Las partes pueden ser usadas como subcomponentes por defecto" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Comprable" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Las partes son comprables por defecto" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Vendible" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Las partes se pueden vender por defecto" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Las partes son rastreables por defecto" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Las partes son virtuales por defecto" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Mostrar partes relacionadas" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Mostrar partes relacionadas para una parte" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Datos iniciales de existencias" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Datos iniciales del proveedor" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formato de visualización de Nombre de Parte" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formato para mostrar el nombre de la parte" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Icono por defecto de la categoría de parte" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de lugares decimales en el precio" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Máximo de lugares decimales en el precio" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Usar precios de proveedor" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Anulación del historial de compra" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Usar precio del artículo de almacén" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Edad del precio del artículo de almacén" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Usar precios variantes" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir variantes de precios en los cálculos generales de precios" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Solo variantes activas" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervalo de reconstrucción de precios" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Precios internos" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Habilitar precios internos para partes" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Anulación del precio interno" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Habilitar impresión de etiquetas" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Habilitar impresión de etiquetas desde la interfaz web" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "PPP de la imagen de etiqueta" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Habilitar informes" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Habilitar generación de informes" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Modo de depuración" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Generar informes en modo de depuración (salida HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Registrar errores de reportes" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registrar errores ocurridos al generar reportes" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Tamaño de página" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Tamaño de página predeterminado para informes PDF" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forzar unidades de parámetro" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Seriales únicos globalmente" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Eliminar existencias agotadas" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Plantilla de código de lote" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Expiración de stock" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Habilitar la funcionalidad de expiración de stock" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vender existencias caducadas" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Permitir venta de existencias caducadas" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Tiempo histórico de Stock" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Crear Stock Caducado" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Permitir crear con stock caducado" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Control de Stock" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Icono por defecto de ubicación de almacén" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Mostrar Articulos de Stock Instalados" -#: common/setting/system.py:744 +#: common/setting/system.py:757 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:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Permitir transferencia Sin Existencias" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Armado" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Requerir Dueño Responsable" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Se debe asignar un dueño responsable a cada orden" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Requerir Parte Activa" -#: common/setting/system.py:778 +#: common/setting/system.py:791 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:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Requerir Parte Bloqueada" -#: common/setting/system.py:784 +#: common/setting/system.py:797 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:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Bloquear hasta que los Tests pasen" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Habilitar órdenes de devolución" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Patrón de referencia de orden de devolución" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Editar ordenes de devolución completadas" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Venta" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Envío Predeterminado de Ordenes de Venta" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Editar Ordenes de Venta Completados" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como completados" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Patrón de Referencia de Orden de Compra" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Editar Ordenes de Compra Completados" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Convertir moneda" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Ordenes de compra" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Habilitar función de contraseña olvidada" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Habilitar registro" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Habilitar SSO" -#: common/setting/system.py:937 +#: 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:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Habilitar registro SSO" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Habilitar sincronización de grupo SSO" -#: common/setting/system.py:952 +#: 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Clave de grupo SSO" -#: common/setting/system.py:959 +#: 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Mapa del grupo SSO" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Eliminar grupos fuera de SSO" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email requerido" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Requiere usuario para suministrar correo al registrarse" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Auto-rellenar usuarios SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Correo dos veces" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Contraseña dos veces" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Dominios permitidos" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupo al registrarse" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Forzar MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Los usuarios deben utilizar seguridad multifactor." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Comprobar complementos al iniciar" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Revisar actualizaciones del plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Habilitar comprobaciones periódicas para actualizaciones de plugins instalados" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Habilitar integración de URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Habilitar plugins para añadir rutas de URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Habilitar integración de navegación" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Habilitar plugins para integrar en la navegación" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Habilitar integración de la aplicación" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Habilitar plugins para añadir aplicaciones" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Habilitar integración de programación" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Habilitar plugins para ejecutar tareas programadas" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Habilitar integración de eventos" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Habilitar plugins para responder a eventos internos" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Habilitar integración de interfaz" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Habilitar complementos para integrar en la interfaz de usuario" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Habilitar códigos de proyecto para rastrear proyectos" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Excluir Ubicaciones Externas" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Periodo de inventario automático" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Mostrar nombres completos de los usuarios" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Mostrar nombres completos de usuarios en lugar de nombres de usuario" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Habilitar datos de estación de prueba" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Recibir reportes de error" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Recibir notificación de errores del sistema" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Últimas impresoras usadas" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "La parte está activa" msgid "Manufacturer is Active" msgstr "El fabricante está activo" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Empresa" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Tiene Stock" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Empresas" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Descripción de la empresa" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Descripción de la empresa" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Página web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL del sitio web de la empresa" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Teléfono" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Teléfono de contacto" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Correo electrónico de contacto" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contacto" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Punto de contacto" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Enlace a información externa de la empresa" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "¿Esta empresa está activa?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "¿Es cliente?" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "¿Vendes artículos a esta empresa?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "¿Es proveedor?" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "¿Compras artículos de esta empresa?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "¿Es productor?" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "¿Esta empresa fabrica partes?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Moneda predeterminada utilizada para esta empresa" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Dirección" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Direcciones" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Seleccionar empresa" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Título de dirección" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Título que describe la entrada de dirección" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Dirección principal" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Establecer como dirección principal" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Línea 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Dirección línea 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Línea 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Dirección línea 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Código postal" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Ciudad/región" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Código postal de ciudad/región" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Estado/provincia" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Estado o provincia" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "País" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Dirección de país" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notas de envío de mensajería" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notas para el mensajero de envío" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Notas de envío internas" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notas de envío para uso interno" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Enlace a información de dirección (externa)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Parte del fabricante" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Parte base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Seleccionar parte" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Seleccionar fabricante" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Número de parte de fabricante" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL para el enlace de parte del fabricante externo" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Descripción de la parte del fabricante" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Las unidades de paquete deben ser mayor que cero" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Proveedor" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Seleccionar proveedor" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unidad de mantenimiento de stock de proveedores" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Seleccionar parte del fabricante" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL del enlace de parte del proveedor externo" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Descripción de la parte del proveedor" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "costo base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Cargo mínimo (p. ej., cuota de almacenamiento)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Paquetes" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Embalaje de partes" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Cantidad de paquete" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "múltiple" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Pedido múltiple" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Cantidad disponible del proveedor" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilidad actualizada" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Fecha de última actualización de los datos de disponibilidad" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Moneda predeterminada utilizada para este proveedor" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Nombre de la empresa" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 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:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "La columna no existe en el archivo de datos" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "El campo no existe en el modelo destino" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "El campo seleccionado es de solo lectura" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Sesión de importación" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Campo" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Columna" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Número de fila" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Datos de la fila original" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Errores" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Válido" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Número de copias a imprimir para cada etiqueta" msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Desconocido" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupo" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Referencia del pedido" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Destacado" @@ -4728,7 +4828,7 @@ msgstr "Destacado" msgid "Has Project Code" msgstr "Tiene Código de Proyecto" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Creado por" @@ -4764,57 +4864,69 @@ msgstr "Fecha objetivo antes" msgid "Target Date After" msgstr "Fecha objetivo después" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Tiene Precio" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Completado antes de" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Completado después de" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Orden" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Orden completada" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Componente interno" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Orden pendiente" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Completados" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Tiene envío" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Orden de compra" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Orden de compra" msgid "Sales Order" msgstr "Orden de Venta" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Precio Total" msgid "Total price for this order" msgstr "Precio total para este pedido" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Moneda de pedido" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Moneda para este pedido (dejar en blanco para utilizar el valor predeter msgid "This order is locked and cannot be modified" msgstr "Este pedido está bloqueado y no puede ser modificado" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "El contacto no coincide con la empresa seleccionada" -#: order/models.py:385 +#: order/models.py:387 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:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Descripción del pedido (opcional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Seleccione el código del proyecto para este pedido" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Enlace a Url externa" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Fecha de inicio" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Fecha de inicio programada para este pedido" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Fecha objetivo" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Fecha de emisión" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Fecha de expedición del pedido" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Usuario o grupo responsable de este pedido" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Punto de contacto para este pedido" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Dirección de la empresa para este pedido" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Referencia del pedido" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Estado" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Estado de la orden de compra" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Empresa de la cual se están encargando los artículos" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Referencia del proveedor" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Código de referencia de pedido del proveedor" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "recibido por" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "La fecha de pedido fue completada" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destinación" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Destino para los artículos recibidos" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "El proveedor de la parte debe coincidir con el proveedor de PO" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "La partida no coincide con la orden de compra" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "La cantidad debe ser un número positivo" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Empresa a la que se venden los artículos" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Estado de la orden de venta" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Referencia del cliente " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Código de referencia de pedido del cliente" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Fecha de envío" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "La orden ya fue completada" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "La orden ya fue cancelada" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Sólo una orden abierta puede ser marcada como completa" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Este pedido está bloqueado y no puede ser modificado" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Cantidad del artículo" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Referencia de partida" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Notas de partida" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Descripción de partida (opcional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contexto adicional para esta línea" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Precio unitario" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "La parte del proveedor debe coincidir con el proveedor" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Parte del proveedor" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Recibido" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Número de artículos recibidos" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Precio de Compra" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Precio de compra unitario" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Precio de Venta" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Precio de venta unitario" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Cantidad enviada" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Fecha del envío" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Fecha de entrega" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Fecha de entrega del envío" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Revisado por" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Usuario que revisó este envío" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envío" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Número de envío" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Número de Seguimiento" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Información de seguimiento del envío" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Número de factura" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Número de referencia para la factura asociada" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "El envío ya ha sido enviado" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "El envío no tiene artículos de stock asignados" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "El artículo de stock no ha sido asignado" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La cantidad de asignación no puede exceder la cantidad de stock" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Cantidad asignada debe ser mayor que cero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "La cantidad debe ser 1 para el stock serializado" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "La orden de venta no coincide con el envío" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "El envío no coincide con el pedido de venta" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Línea" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Referencia del envío del pedido de venta" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Ítem" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Seleccionar artículo de stock para asignar" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Especificar la cantidad de asignación de stock" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Referencia de la orden de devolución" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Empresa de la cual se están devolviendo los artículos" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Estado de la orden de devolución" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Seleccionar el artículo a devolver del cliente" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Fecha de recepción" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Resultado" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Salida para esta partida" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID del Pedido" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID del pedido a duplicar" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Copiar líneas" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Copiar elementos de línea del pedido original" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Copiar líneas adicionales" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Partidas" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Líneas completadas" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplicar pedido" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Especificar opciones para duplicar este pedido" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "ID de pedido no válido" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Nombre del proveedor" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "El pedido no puede ser cancelado" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Permitir cerrar el pedido con partidas incompletas" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "El pedido tiene partidas incompletas" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "El pedido no está abierto" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Precio automático" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Moneda del precio de compra" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Combinar artículos" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Número de parte interna" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Nombre interno de parte" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Debe especificar la parte del proveedor" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "La orden de compra debe especificarse" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "El proveedor debe coincidir con la orden de compra" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "La orden de compra debe coincidir con el proveedor" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Partida" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Seleccione la ubicación de destino para los artículos recibidos" -#: order/serializers.py:808 +#: order/serializers.py:863 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:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Fecha de Expiración" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Introduzca números de serie para artículos de almacén entrantes" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Código de barras escaneado" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Código de barras en uso" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Se deben proporcionar las partidas" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Se requiere ubicación de destino" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Los valores del código de barras deben ser únicos" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Envíos" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Envíos completados" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Moneda del precio de venta" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Elementos asignados" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "No se proporcionaron detalles de envío" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "La cantidad debe ser positiva" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Introduzca números de serie para asignar" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "El envío ya ha sido enviado" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "El envío no está asociado con este pedido" -#: order/serializers.py:1777 +#: 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:1784 +#: 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:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Partida de orden de devolución" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "La partida no coincide con la orden de devolución" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "La partida ya ha sido recibida" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Cantidad a devolver" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Moneda de precio de línea" @@ -5598,146 +5742,150 @@ msgstr "Reembolso" msgid "Reject" msgstr "Rechazo" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Orden de compra atrasada" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "La orden de compra {po} está atrasada" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Orden de venta atrasada" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La orden de venta {so} está atrasada" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Favoritos" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Profundidad" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtrar por profundidad de categoría" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Nivel superior" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtrar por categorías de nivel superior" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "En cascada" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Tiene resultados" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Categoría de parte" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Categorías de parte" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Ubicación Predeterminada" @@ -5778,7 +5926,7 @@ msgstr "Palabras clave por defecto para partes en esta categoría" msgid "Icon" msgstr "Icono" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Icono (opcional)" @@ -5799,1025 +5947,1050 @@ msgstr "Valor predeterminado" msgid "Default Parameter Value" msgstr "Valor de parámetro por defecto" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Partes" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN duplicado no permitido en la configuración de partes" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "La revisión de parte duplicada ya existe." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Parte con este nombre, IPN y revisión ya existe." -#: part/models.py:1075 +#: part/models.py:1070 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:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nombre de la parte" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Es plantilla" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "¿Es esta parte una parte de la plantilla?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Descripción de parte (opcional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Palabras claves" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Categoría de parte" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Revisión de parte o número de versión" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisión" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Variante de" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "¿Dónde se almacena este artículo normalmente?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Expiración por defecto" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Stock mínimo" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Nivel mínimo de stock permitido" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Unidades de medida para esta parte" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "¿Se puede construir esta parte a partir de otras partes?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "¿Se puede utilizar esta parte para construir otras partes?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "¿Esta parte tiene seguimiento de objetos únicos?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "¿Se puede comprar esta parte a proveedores externos?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "¿Se puede vender esta parte a los clientes?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "¿Está activa esta parte?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Las partes bloqueadas no pueden ser editadas" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Suma de verificación de BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Suma de verificación de BOM almacenada" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM comprobado por" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Fecha BOM comprobada" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Creación de Usuario" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Dueño responsable de esta parte" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Vender múltiples" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Moneda utilizada para almacenar en caché los cálculos de precios" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Costo mínimo de BOM" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Costo mínimo de partes de componentes" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Costo máximo de BOM" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Costo máximo de partes de componentes" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Costo mínimo de compra" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Costo histórico mínimo de compra" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Costo máximo de compra" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Costo histórico máximo de compra" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Precio interno mínimo" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Costo mínimo basado en precios reducidos internos" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Precio interno máximo" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Costo máximo basado en precios reducidos internos" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Precio mínimo de proveedor" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Precio mínimo de la parte de proveedores externos" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Precio máximo de proveedor" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Precio máximo de la parte de proveedores externos" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Costo mínimo de variante" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Costo mínimo calculado de las partes variantes" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Costo máximo de variante" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Costo máximo calculado de las partes variantes" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Costo mínimo" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Anular el costo mínimo" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Costo máximo" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Reemplazar coste máximo" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Costo mínimo general calculado" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Precio de venta mínimo" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Precio de venta mínimo basado en precios reducidos" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Precio de venta máximo" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Precio de venta máximo basado en precios reducidos" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Costo de venta mínimo" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Precio de venta mínimo histórico" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Costo de Venta Máximo" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Precio de venta máximo histórico" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Número de artículos" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Fecha" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Costo de Stock Mínimo" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Costo mínimo estimado del stock disponible" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nombre de prueba" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Introduzca un nombre para la prueba" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Descripción de prueba" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Introduce la descripción para esta prueba" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Requerido" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "¿Es necesario pasar esta prueba?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Requiere valor" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Adjunto obligatorio" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Seleccionar parte principal" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sub parte" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Seleccionar parte a utilizar en BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Cantidad del artículo en BOM" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Este artículo BOM es opcional" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Referencia de artículo de BOM" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notas del artículo de BOM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Suma de verificación" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Suma de verificación de línea de BOM" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validado" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Este artículo de BOM ha sido validado" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "La cantidad debe ser un valor entero para las partes rastreables" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Debe especificar la subparte" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Ítem de BOM sustituto" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Artículo BOM superior" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Sustituir parte" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Seleccionar parte relacionada" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Nota para esta relación" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Categoría principal de parte" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Subcategorías" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Moneda de compra de ítem de stock" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Parte original" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Seleccione la parte original a duplicar" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Copiar Imagen" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Copiar imagen desde la parte original" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copiar BOM" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Copiar Parámetros" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Copiar datos del parámetro de la parte original" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Copiar Notas" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Cantidad Inicial de Stock" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Seleccione proveedor (o déjelo en blanco para saltar)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleccionar fabricante (o dejar en blanco para saltar)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Número de parte del fabricante" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "La empresa seleccionada no es un proveedor válido" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "La empresa seleccionada no es un fabricante válido" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Nombre de categoría" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "En construcción" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Elementos de stock" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Inventario Total" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Duplicar Parte" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Stock Inicial" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Crear Parte con cantidad inicial de stock" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Información del proveedor" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Añadir información inicial del proveedor para esta parte" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Copiar Parámetros de Categoría" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Copiar plantillas de parámetro de la categoría de partes seleccionada" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Imagen Existente" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "El archivo de imagen no existe" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Validación de Lista de Materiales" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Puede construir" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Precio mínimo" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Anular el valor calculado para precio mínimo" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Precio mínimo de moneda" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Precio máximo" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Precio máximo de moneda" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Actualizar" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Seleccionar parte de la que copiar BOM" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Eliminar Datos Existentes" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Eliminar artículos BOM existentes antes de copiar" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Incluye Heredado" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Omitir filas no válidas" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Activar esta opción para omitir filas inválidas" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Copiar partes sustitutas" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notificación por bajo stock" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "Impresión de etiquetas fallida" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "Proporciona soporte nativo para códigos de barras" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Impresora de etiquetas PDF de InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Proporciona soporte nativo para imprimir etiquetas PDF" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Modo de depuración" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activar modo de depuración - devuelve código HTML en lugar de PDF" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "El complemento no está instalado" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Instalación del complemento no encontrada" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Complemento" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "No se encontró autor" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "El complemento requiere al menos la versión {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "El complemento requiere como máximo la versión {v}" @@ -7884,55 +8070,55 @@ msgstr "Instalación no confirmada" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Activar complemento" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Activar este complemento" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "Dimensiones de etiqueta inválidas" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "Carta" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nombre de la plantilla" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Adjuntar al modelo al imprimir" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Patrón de Nombre de archivo" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtros" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Tamaño de página para reportes PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Ancho [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Ancho de la etiqueta, especificado en mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Altura de la etiqueta, especificada en mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Fragmento" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Archivo fragmento de informe" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Descripción de archivo de fragmento" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Activo" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Reportar archivo de activos" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Descripción del archivo de activos" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Selecciona la plantilla de etiqueta" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Complemento de impresión" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Selecciona el complemento a usar para imprimir etiquetas" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de serie" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Elementos instalados" @@ -8248,184 +8438,196 @@ msgstr "Ningún resultado (requerido)" msgid "No result" msgstr "Sin resultados" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Ubicación principal" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtrar por ubicación principal" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Nombre de pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "El nombre de la pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Nombre de la pieza (expresión regular)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Pieza IPN (insensible a mayúsculas y minúsculas)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Pieza IPN (insensible a mayúsculas y minúsculas)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Pieza IPN (expresión regular)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Stock mínimo" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Stock máximo" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Código de estado" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Ubicación externa" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Instalado en otro artículo de existencias" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Árbol de piezas" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Actualizado antes" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Actualizado después" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Inventario antes" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Inventario después" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Desactualizado" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Cantidad requerida" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Debe suministrarse una parte válida" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Ubicación de Stock" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Ubicaciones de Stock" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Propietario" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Seleccionar Propietario" @@ -8461,7 +8663,7 @@ msgstr "Seleccionar Propietario" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Externo" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Se debe especificar la pieza" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "El objeto no puede pertenecer a sí mismo" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Artículo de stock padre" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Parte base" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "¿Dónde se encuentra este artículo de stock?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Empaquetar este artículo de stock se almacena en" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Instalado en" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "¿Está este artículo instalado en otro artículo?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Número de serie para este artículo" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Código de lote para este artículo de stock" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Cantidad de Stock" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Build de origen" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Build para este item de stock" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Orden de compra de origen" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Orden de compra para este artículo de stock" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Orden de venta de destino" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Eliminar al agotar" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Eliminar este artículo de stock cuando se agoten las existencias" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Precio de compra único en el momento de la compra" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Convertido a parte" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "La parte no está establecida como rastreable" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Cantidad debe ser un entero" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Los números de serie deben ser proporcionados como una lista" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "La cantidad no coincide con los números de serie" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 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:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Artículo de stock está instalado en otro artículo" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Artículo de stock contiene otros artículos" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Artículo de stock ha sido asignado a un cliente" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "El artículo de stock está en producción" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Stock serializado no puede ser combinado" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Artículos de Stock Duplicados" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Los artículos de stock deben referirse a la misma parte" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Los códigos de estado del stock deben coincidir" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Notas de entrada" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Debe proporcionarse un valor para esta prueba" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "El archivo adjunto debe ser subido para esta prueba" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Resultado de la prueba" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Valor de salida de prueba" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Adjunto de resultados de prueba" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Notas de prueba" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Finalizó" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Elemento padre" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Introduzca números de serie para nuevos artículos" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Número de pieza del proveedor" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Elementos secundarios" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Introduzca el número de artículos de stock para serializar" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Ubicación de stock de destino" -#: stock/serializers.py:735 +#: stock/serializers.py:760 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:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Números de serie ya existen" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Añadir nota de transacción (opcional)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sub-ubicación" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "La parte debe ser vendible" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "El artículo está asignado a una orden de venta" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "El artículo está asignado a una orden de creación" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Cliente para asignar artículos de stock" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "La empresa seleccionada no es un cliente" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Notas de asignación de stock" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Debe proporcionarse una lista de artículos de stock" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notas de fusión de stock" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Permitir proveedores no coincidentes" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Permitir estado no coincidente" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Debe proporcionar al menos dos artículos de stock" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Sin cambios" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Valor de clave primaria de Stock" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "No hay existencias del artículo" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Notas de transacción de stock" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Última vez que se usó el token" msgid "Revoked" msgstr "Revocado" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Permiso establecido" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Vista" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Permiso para ver artículos" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Añadir" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Permiso para añadir artículos" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Cambiar" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Permisos para editar artículos" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Eliminar" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Permiso para eliminar artículos" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Ordenes de compra" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Órdenes de venta" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Ordenes de devolución" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nombre de usuario" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Nombre" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Nombre del usuario" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Apellido" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Apellido del usuario" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Dirección de correo del usuario" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personal" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Tiene este usuario permisos de personal" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superusuario" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Es este usuario un superusuario" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Esta cuenta de usuario está activa" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Su cuenta ha sido creada." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 e9cc6ebe4e..b4bba3f73e 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Spanish, Mexico\n" "Language: es_MX\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "endpoint API no encontrado" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Lista de artículos o filtros deben ser proporcionados para la operación en bloque" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Los artículos deben ser provistos como una lista" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Lista de artículos inválida" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Los filtros deben ser provistos como un diccionario" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtros proporcionados inválidos" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Todos los filtros sólo deben ser usados como verdaderos" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Ningún artículo coincide con el criterio proporcionado" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "El usuario no tiene permiso para ver este modelo" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" @@ -112,13 +105,13 @@ msgstr "Ingrese la fecha" msgid "Invalid decimal value" msgstr "Número decimal inválido" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notas" @@ -131,75 +124,91 @@ msgstr "El valor '{name}' no aparece en formato de patrón" msgid "Provided value does not match required pattern: " msgstr "El valor proporcionado no coincide con el patrón requerido: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 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:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "No se ha proporcionado un número de serie" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Serie duplicada" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grupo inválido: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Numeros de serie no encontrados" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Eliminar etiquetas HTML de este valor" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Los datos contienen contenido de markdown prohibido" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Error de conexión" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "El servidor respondió con código de estado no válido" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Se ha producido una excepción" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "El tamaño de la imagen es demasiado grande" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "La descarga de imagen excedió el tamaño máximo" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "El servidor remoto devolvió una respuesta vacía" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "La URL proporcionada no es un archivo de imagen válido" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Correo electrónico" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "La referencia debe coincidir con la expresión regular {pattern}" msgid "Reference number is too large" msgstr "El número de referencia es demasiado grande" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Selección no válida" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nombre" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descripción" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descripción (opcional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Ruta" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Los nombres duplicados no pueden existir bajo el mismo padre" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notas de Markdown (opcional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Datos de código de barras" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Datos de código de barras de terceros" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash del Código de barras" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash único de datos de código de barras" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Fallo en la tarea" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "La tarea en segundo plano '{f}' falló después de {n} intentos" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Error de servidor" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Se ha registrado un error por el servidor." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Debe ser un número válido" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Moneda" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Seleccionar moneda de las opciones disponibles" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Imagen remota" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL de imagen remota" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "La descarga de imágenes desde la URL remota no está habilitada" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Error al descargar la imagen desde la URL remota" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Chino (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chino (Tradicional)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Unidad física inválida" msgid "Not a valid currency code" msgstr "No es un código de moneda válido" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Estado del pedido" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Construcción o Armado Superior" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Incluye Variantes" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Incluye Variantes" msgid "Part" msgstr "Parte" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categoría" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Construir antepasado" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Asignado a mí" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Asignadas a" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Creado antes de" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Creado después de" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Tiene fecha inicial" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Fecha objetivo antes de" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Fecha objetivo después de" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Completado antes de" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Completado después de" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "La compilación debe cancelarse antes de poder ser eliminada" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumible" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montaje" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Comprobable" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Pedido pendiente" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Asignadas" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "En pedido" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Construir órden" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Ubicación" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Construir órdenes" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "BOM de ensamblado no ha sido validado" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Se debe especificar un usuario o grupo responsable" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "La parte del pedido de construcción no puede ser modificada" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Número de orden de construcción o armado" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Número de orden de construcción o armado" msgid "Reference" msgstr "Referencia" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Breve descripción de la construcción (opcional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Seleccionar parte a construir o armar" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referencia de orden de venta" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Ubicación de la fuente" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Ubicación de destino" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Cantidad a crear" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Número de objetos existentes a construir" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Elementos completados" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Número de productos en stock que se han completado" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Estado de la construcción" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Código de estado de construcción" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Numero de lote" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Número de lote de este producto final" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Fecha de Creación" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Fecha límite de finalización" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Fecha de finalización" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "terminado por" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "El usuario que emitió esta orden" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Usuario o grupo responsable de esta orden de construcción" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Link externo" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Enlace a URL externa" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Prioridad de construcción" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioridad de esta orden de construcción" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Código del proyecto" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Código de proyecto para esta orden de ensamble" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "El pedido {build} ha sido procesado" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Pedido #[order] ha sido procesado" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "No se ha especificado salida de construcción" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "La construcción de la salida ya está completa" -#: build/models.py:1019 +#: build/models.py:1030 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:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "La cantidad debe ser mayor que cero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "La cantidad no puede ser mayor que la cantidad de salida" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Construir línea de pedido" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Ensamblar equipo" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Cantidad" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Cantidad requerida para orden de ensamble" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "La cantidad debe ser 1 para el stock serializado" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Artículo de stock sobreasignado" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Artículo de stock" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Producto original de stock" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Cantidad de stock a asignar para construir" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Instalar en" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Artículo de stock de destino" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Nivel de construcción" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nombre de parte" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Esta salida de construcción ya ha sido completada" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Esta salida de construcción no está completamente asignada" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Ingrese la cantidad para la producción de la construcción" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Cantidad entera requerida para partes rastreables" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Números de serie" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Introduzca los números de serie de salidas de construcción" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Ubicación de stock para objetos construidos" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Autoasignar Números de Serie" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Debe proporcionarse una lista de salidas de construcción" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Ubicación de almacén para salidas descartadas" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Descartar asignaciones" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar cualquier asignación de existencias para las salidas descartadas" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Razón para descartar la salida de ensamble(s)" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Ubicación para las salidas de construcción completadas" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Aceptar Asignación Incompleta" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Completar salidas si el inventario no se ha asignado completamente" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consumir Stock Asignado" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Eliminar salidas incompletas" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "No permitido" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Aceptar como consumido por este pedido de construcción" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Liberar antes de completar esta orden de construcción" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Stock sobreasignado" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Algunos artículos de inventario han sido sobreasignados" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Aceptar no asignado" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "El stock requerido no ha sido completamente asignado" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Aceptar incompleto" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "La cantidad de construcción requerida aún no se ha completado" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "La orden de construcción tiene órdenes hijas de construcción abiertas" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Orden de construcción debe estar en estado de producción" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "El orden de construcción tiene salidas incompletas" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linea de ensamble" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:879 +#: build/serializers.py:885 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:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Crear partida" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "El artículo debe estar en stock" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Cantidad disponible ({q}) excedida" -#: build/serializers.py:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Debe proporcionarse la adjudicación de artículos" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Excluir ubicación" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Excluir artículos de stock de esta ubicación seleccionada" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Stock intercambiable" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Sustituir stock" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Permitir la asignación de partes sustitutas" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Elementos opcionales" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Asignar artículos de la BOM opcionales para construir la orden" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Error al iniciar la tarea de asignación automática" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Referencia BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID de la parte BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nombre de parte la BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Parte del proveedor" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Cantidad Asignada" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Referencia de orden de Ensamblado" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Nombre de la categoría por pieza" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Rastreable" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Heredado" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Item de Lista de Materiales" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "En producción" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Stock externo" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Stock Disponible" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Stock sustituto disponible" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Stock variable disponible" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "En espera" msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Terminado" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Stock requerido para la orden de construcción" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Orden de construcción atrasada" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "El pedido de construcción {bo} está atrasado" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "¿Es enlace?" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "¿Es archivo?" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "El usuario no tiene permiso para eliminar estos adjuntos" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "El usuario no tiene permiso para eliminar este adjunto" @@ -1551,798 +1539,822 @@ msgstr "No se han proporcionado códigos de divisa válidos" msgid "No plugin" msgstr "Sin plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Etiqueta del código del proyecto" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Actualizado" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Fecha y hora de la última actualización" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Código único del proyecto" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Descripción del proyecto" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Usuario o grupo responsable de este projecto" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Tecla de ajustes" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valor de ajuste" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "El valor debe ser un valor booleano" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "El valor debe ser un entero" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "El valor debe ser un número válido" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "El valor no pasa las comprobaciones de validación" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Cadena de clave debe ser única" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Usuario" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Cantidad de salto de precio" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Precio" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Precio unitario a la cantidad especificada" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Endpoint" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nombre para este webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Activo" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Está activo este webhook" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token para el acceso" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Clave" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Secreto compartido para HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID de mensaje" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identificador único para este mensaje" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Servidor desde el cual se recibió este mensaje" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Encabezado" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Encabezado del mensaje" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Cuerpo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Cuerpo de este mensaje" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endpoint en el que se recibió este mensaje" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Trabajado en" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "¿El trabajo en este mensaje ha terminado?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Título" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Enlace" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publicado" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Resumen" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Leer" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "¿Esta noticia ya fue leída?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Archivo de imagen" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Tipo de modelo destino para esta imagen" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Unidad personalizada" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "El símbolo de la unidad debe ser único" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Nombre de unidad debe ser un identificador válido" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nombre de unidad" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Símbolo de unidad opcional" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definición" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definición de unidad" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Archivo adjunto" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Archivo no encontrado" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Falta enlace externo" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Seleccionar archivo para adjuntar" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Comentario" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Comentario de archivo adjunto" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Fecha de carga" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Fecha de carga del archivo" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Tamaño del archivo" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Tamaño del archivo en bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Tipo de modelo no válido especificado para el archivo adjunto" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Conjunto de estado de referencia" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Conjunto de estado extendido con este estado personalizado" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Llave lógica" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valor" -#: common/models.py:2114 +#: common/models.py:2196 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:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Nombre del estado" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que se mostrará en el frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Color" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Color que se mostrará en el frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modelo" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Modelo con el que este estado está asociado" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "El modelo debe ser seleccionado" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "La clave debe ser seleccionada" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "La clave lógica debe ser seleccionada" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "La clave debe ser distinta de la clave lógica" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Debe proporcionarse una clase de estado de referencia válida" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Lista de selección" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Listas de Selección" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Nombre de la lista de selección" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Descripción de la lista de selección" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "¿Está bloqueada esta lista de selección?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "¿Se puede utilizar esta lista de selección?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Complemento de origen" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Complemento que proporciona la lista de selección" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Cadena de origen" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Cadena opcional que identifica la fuente usada para esta lista" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Entrada por defecto" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Entrada predeterminada para esta lista de selección" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Creado" -#: common/models.py:2296 +#: common/models.py:2378 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:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Última actualización" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Entrada de lista de selección" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Entradas de la lista de selección" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Lista de selección a la que pertenece esta entrada" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Valor del elemento de la lista de selección" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Etiqueta para la entrada de lista de selección" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Descripción de la entrada de lista de selección" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "¿Está activa esta entrada de la lista de selección?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Plantilla de parámetro" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "El nombre de parámetro en la plantilla tiene que ser único" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nombre de Parámetro" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unidades" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Casilla de verificación" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "¿Es este parámetro una casilla de verificación?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Opciones" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opciones válidas para este parámetro (separados por comas)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Lista de selección para este parámetro" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Opción inválida para el valor del parámetro" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Plantilla" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Datos" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Valor del parámetro" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Nota" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Campo de nota opcional" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Escanear código de barras" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Datos de código de barras" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Usuario que escaneó el código de barras" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Fecha y hora del escaneo de código de barras" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Dispositivo URL que procesó el código de barras" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Datos de contexto para el escaneo de código de barras" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Respuesta" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Respuesta de datos del escaneo de código de barras" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultado" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "¿El escaneo de código de barras fue exitoso?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Clave" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Artículos Recibidos" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Está en ejecución" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Tareas pendientes" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tareas Programadas" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tareas fallidas" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Identificación de Tarea" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Identificación de tarea única" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Bloquear hora" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nombre de la tarea" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Función" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nombre de la Función" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumentos de la tarea" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argumentos de palabra clave" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argumentos de palabra clave de tarea" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nombre de Archivo" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista de selección bloqueada" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Sin grupo" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "La URL del sitio está bloqueada por su configuración" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Reinicio requerido" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Se ha cambiado una configuración que requiere un reinicio del servidor" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migraciones pendientes" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Número de migraciones de base de datos pendientes" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nombre de la instancia del servidor" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Descriptor de cadena para la instancia del servidor" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Usar nombre de instancia" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Utilice el nombre de la instancia en la barra de título" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Restringir mostrar 'acerca de'" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Mostrar la modal `about` solo para superusuarios" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nombre de empresa" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nombre interno de empresa" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL Base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL base para la instancia del servidor" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Moneda predeterminada" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Seleccione la moneda base para los cálculos de precios" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Monedas admitidas" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Listado de códigos de divisa soportados" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervalo de actualización de moneda" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "días" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Plugin de Actualización de Moneda" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Plugin de actualización de moneda a usar" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Descargar desde URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Permitir la descarga de imágenes y archivos remotos desde la URL externa" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Límite de tamaño de descarga" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Tamaño máximo de descarga permitido para la imagen remota" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Agente de usuario usado para descargar desde la URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Permitir reemplazar el agente de usuario utilizado para descargar imágenes y archivos desde URL externa (dejar en blanco para el valor predeterminado)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validación estricta de URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Requerir especificación de esquema al validar URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Actualizar intervalo de actualización" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Con qué frecuencia comprobar actualizaciones (establecer a cero para desactivar)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Copia de seguridad automática" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Activar copia de seguridad automática de los archivos de base de datos y medios" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervalo de respaldo automático" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Especificar número de días entre eventos automatizados de copia de seguridad" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervalo de eliminación de tareas" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Los resultados de las tareas en segundo plano se eliminarán después del número especificado de días" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervalo de eliminación de registro de errores" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Los registros de errores se eliminarán después del número especificado de días" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervalo de eliminación de notificaciones" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Las notificaciones de usuario se eliminarán después del número especificado de días" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Soporte de código de barras" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Habilitar el soporte para escáner de códigos de barras en la interfaz web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Guardar resultados de código de barras" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Guardar resultados de código de barras en la base de datos" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Número máximo de escaneos de código de barras" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Número máximo de resultados de escaneo de código de barras para almacenar" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Retraso de entrada de código de barras" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tiempo de retraso en la lectura de códigos de barras" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Soporte para Webcam de código de barras" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Permitir escaneo de código de barras a través de webcam en el navegador" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Mostrar datos del código de barra como texto en el navegador" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Complemento para generar códigos de barra" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revisiones de partes" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Habilitar campo de revisión para parte" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Permitir IPN duplicado" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que varias partes compartan el mismo IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Permitir editar IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copiar parte de datos BOM" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Copiar datos BOM por defecto al duplicar una parte" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copiar parámetros de parte" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copiar parte de datos de prueba" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copiar plantillas de parámetros de categoría" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Las partes son plantillas por defecto" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Componente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Las partes pueden ser usadas como subcomponentes por defecto" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Comprable" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Las partes son comprables por defecto" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Vendible" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Las partes se pueden vender por defecto" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Las partes son rastreables por defecto" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Las partes son virtuales por defecto" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Mostrar partes relacionadas" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Mostrar partes relacionadas para una parte" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Datos iniciales de existencias" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Datos iniciales del proveedor" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formato de visualización de Nombre de Parte" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formato para mostrar el nombre de la parte" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Icono por defecto de la categoría de parte" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de lugares decimales en el precio" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Máximo de lugares decimales en el precio" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Usar precios de proveedor" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Anulación del historial de compra" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Usar precio del artículo de almacén" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Edad del precio del artículo de almacén" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Usar precios variantes" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir variantes de precios en los cálculos generales de precios" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Solo variantes activas" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervalo de reconstrucción de precios" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Precios internos" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Habilitar precios internos para partes" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Anulación del precio interno" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Habilitar impresión de etiquetas" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Habilitar impresión de etiquetas desde la interfaz web" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "PPP de la imagen de etiqueta" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Habilitar informes" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Habilitar generación de informes" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Modo de depuración" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Generar informes en modo de depuración (salida HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Registrar errores de reportes" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registrar errores ocurridos al generar reportes" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Tamaño de página" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Tamaño de página predeterminado para informes PDF" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forzar unidades de parámetro" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Seriales únicos globalmente" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Eliminar existencias agotadas" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Plantilla de código de lote" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Expiración de stock" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Habilitar la funcionalidad de expiración de stock" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vender existencias caducadas" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Permitir venta de existencias caducadas" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Tiempo histórico de Stock" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Crear Stock Caducado" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Permitir crear con stock caducado" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Control de Stock" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Icono por defecto de ubicación de almacén" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Mostrar Articulos de Stock Instalados" -#: common/setting/system.py:744 +#: common/setting/system.py:757 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:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Revisar BOM al instalar artículos" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Permitir transferencia Sin Existencias" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Armado" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Requerir Dueño Responsable" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Se debe asignar un dueño responsable a cada orden" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Requerir Parte Activa" -#: common/setting/system.py:778 +#: common/setting/system.py:791 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:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Requerir Parte Bloqueada" -#: common/setting/system.py:784 +#: common/setting/system.py:797 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:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Bloquear hasta que los Tests pasen" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Habilitar órdenes de devolución" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Patrón de referencia de orden de devolución" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Editar ordenes de devolución completadas" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Venta" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Envío Predeterminado de Ordenes de Venta" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Editar Ordenes de Venta Completados" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como completados" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 -msgid "Purchase Order Reference Pattern" -msgstr "Patrón de Referencia de Orden de Compra" - -#: common/setting/system.py:889 -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:901 -msgid "Edit Completed Purchase Orders" -msgstr "Editar Ordenes de Compra Completados" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Patrón de Referencia de Orden de Compra" + +#: common/setting/system.py:918 +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 +msgid "Edit Completed Purchase Orders" +msgstr "Editar Ordenes de Compra Completados" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Ordenes de compra" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Habilitar función de contraseña olvidada" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Habilitar registro" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Habilitar SSO" -#: common/setting/system.py:937 +#: 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:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Habilitar registro SSO" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Habilitar sincronización de grupo SSO" -#: common/setting/system.py:952 +#: 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Clave de grupo SSO" -#: common/setting/system.py:959 +#: 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Mapa del grupo SSO" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Eliminar grupos fuera de SSO" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email requerido" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Requiere usuario para suministrar correo al registrarse" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Auto-rellenar usuarios SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Correo dos veces" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Contraseña dos veces" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Dominios permitidos" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupo al registrarse" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Forzar MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Los usuarios deben utilizar seguridad multifactor." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Comprobar complementos al iniciar" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Revisar actualizaciones del plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Habilitar comprobaciones periódicas para actualizaciones de plugins instalados" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Habilitar integración de URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Habilitar plugins para añadir rutas de URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Habilitar integración de navegación" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Habilitar plugins para integrar en la navegación" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Habilitar integración de la aplicación" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Habilitar plugins para añadir aplicaciones" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Habilitar integración de programación" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Habilitar plugins para ejecutar tareas programadas" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Habilitar integración de eventos" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Habilitar plugins para responder a eventos internos" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Habilitar integración de interfaz" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Habilitar complementos para integrar en la interfaz de usuario" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Excluir Ubicaciones Externas" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Periodo de inventario automático" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Mostrar nombres completos de los usuarios" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Mostrar nombres completos de usuarios en lugar de nombres de usuario" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Habilitar datos de estación de prueba" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Recibir reportes de error" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Recibir notificación de errores del sistema" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Últimas impresoras usadas" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Empresa" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Tiene existencias" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Empresas" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Descripción de la empresa" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Descripción de la empresa" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Página web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL del sitio web de la empresa" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Teléfono" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Teléfono de contacto" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Correo electrónico de contacto" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contacto" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Punto de contacto" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Enlace a información externa de la empresa" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "¿Esta empresa está activa?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "¿Es cliente?" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "¿Vendes artículos a esta empresa?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "¿Es proveedor?" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "¿Compras artículos de esta empresa?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "¿Es productor?" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "¿Esta empresa fabrica partes?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Moneda predeterminada utilizada para esta empresa" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Dirección" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Direcciones" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Seleccionar empresa" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Título de dirección" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Título que describe la entrada de dirección" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Dirección principal" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Establecer como dirección principal" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Línea 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Dirección línea 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Línea 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Dirección línea 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Código postal" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Ciudad/región" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Código postal de ciudad/región" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Estado/provincia" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Estado o provincia" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "País" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Dirección de país" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notas de envío de mensajería" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notas para el mensajero de envío" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Notas de envío internas" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notas de envío para uso interno" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Enlace a información de dirección (externa)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Parte del fabricante" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Parte base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Seleccionar parte" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Seleccionar fabricante" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Número de parte de fabricante" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL para el enlace de parte del fabricante externo" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Descripción de la parte del fabricante" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Las unidades de paquete deben ser mayor que cero" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Proveedor" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Seleccionar proveedor" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unidad de mantenimiento de stock de proveedores" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Seleccionar parte del fabricante" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL del enlace de parte del proveedor externo" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Descripción de la parte del proveedor" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "costo base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Cargo mínimo (p. ej., cuota de almacenamiento)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Paquetes" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Embalaje de partes" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Cantidad de paquete" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "múltiple" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Pedido múltiple" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Cantidad disponible del proveedor" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilidad actualizada" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Fecha de última actualización de los datos de disponibilidad" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Moneda predeterminada utilizada para este proveedor" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Nombre de la empresa" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 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:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "La columna no existe en el archivo de datos" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "El campo no existe en el modelo destino" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "El campo seleccionado es de solo lectura" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Sesión de importación" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Campo" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Columna" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Número de fila" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Datos de la fila original" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Errores" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Válido" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Número de copias a imprimir para cada etiqueta" msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Desconocido" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupo" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Referencia del pedido" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Destacado" @@ -4728,7 +4828,7 @@ msgstr "Destacado" msgid "Has Project Code" msgstr "Tiene Código de Proyecto" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Creado por" @@ -4764,57 +4864,69 @@ msgstr "Fecha objetivo antes de" msgid "Target Date After" msgstr "Fecha objetivo después de" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Tiene Precio" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Completado antes de" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Completado después de" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Orden" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Orden completada" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Componente interno" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Orden pendiente" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Completados" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Tiene envío" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Orden de compra" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Orden de compra" msgid "Sales Order" msgstr "Orden de Venta" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Precio Total" msgid "Total price for this order" msgstr "Precio total para este pedido" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Moneda de pedido" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Moneda para este pedido (dejar en blanco para utilizar el valor predeter msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "El contacto no coincide con la empresa seleccionada" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Descripción del pedido (opcional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Seleccione el código del proyecto para este pedido" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Enlace a Url externa" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Fecha objetivo" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Fecha de emisión" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Fecha de expedición del pedido" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Usuario o grupo responsable de este pedido" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Punto de contacto para este pedido" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Dirección de la empresa para este pedido" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Referencia del pedido" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Estado" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Estado de la orden de compra" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Empresa de la cual se están encargando los artículos" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Referencia del proveedor" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Código de referencia de pedido del proveedor" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "recibido por" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "La fecha de pedido fue completada" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destinación" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Destino para los artículos recibidos" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "El proveedor de la parte debe coincidir con el proveedor de PO" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "La partida no coincide con la orden de compra" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "La cantidad debe ser un número positivo" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Empresa a la que se venden los artículos" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Estado de la orden de venta" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Referencia del cliente " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Código de referencia de pedido del cliente" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Fecha de envío" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "La orden ya fue completada" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "La orden ya fue cancelada" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Sólo una orden abierta puede ser marcada como completa" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Cantidad del artículo" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Referencia de partida" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Notas de partida" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Descripción de partida (opcional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contexto adicional para esta línea" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Precio unitario" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "La parte del proveedor debe coincidir con el proveedor" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Parte del proveedor" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Recibido" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Número de artículos recibidos" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Precio de Compra" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Precio de compra unitario" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Precio de Venta" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Precio de venta unitario" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Cantidad enviada" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Fecha del envío" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Fecha de entrega" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Fecha de entrega del envío" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Revisado por" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Usuario que revisó este envío" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envío" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Número de envío" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Número de Seguimiento" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Información de seguimiento del envío" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Número de factura" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Número de referencia para la factura asociada" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "El envío ya ha sido enviado" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "El envío no tiene artículos de stock asignados" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "El artículo de stock no ha sido asignado" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La cantidad de asignación no puede exceder la cantidad de stock" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Cantidad asignada debe ser mayor que cero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "La cantidad debe ser 1 para el stock serializado" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "La orden de venta no coincide con el envío" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "El envío no coincide con el pedido de venta" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Línea" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Referencia del envío del pedido de venta" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Ítem" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Seleccionar artículo de stock para asignar" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Especificar la cantidad de asignación de stock" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Referencia de la orden de devolución" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Empresa de la cual se están devolviendo los artículos" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Estado de la orden de devolución" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "El artículo de almacén debe ser especificado" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "La cantidad de retorno excede la cantidad de existencias" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "La cantidad de retorno debe ser mayor que cero" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Cantidad inválida para el artículo de stock serializado" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Seleccionar el artículo a devolver del cliente" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Fecha de recepción" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Resultado" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Salida para esta partida" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID del Pedido" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID del pedido a duplicar" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Copiar líneas" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Copiar partida del pedido original" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Copiar líneas adicionales" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Copiar partidas extra del pedido original" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Partidas" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Líneas completadas" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplicar pedido" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Especificar opciones para duplicar este pedido" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "ID de pedido inválido" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Nombre del proveedor" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "El pedido no puede ser cancelado" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Permitir cerrar el pedido con partidas incompletas" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "El pedido tiene partidas incompletas" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "El pedido no está abierto" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Precio automático" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Moneda del precio de compra" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Combinar artículos" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Número de parte interna" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Nombre interno de parte" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Debe especificar la parte del proveedor" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "La orden de compra debe especificarse" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "El proveedor debe coincidir con la orden de compra" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "La orden de compra debe coincidir con el proveedor" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Partida" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Seleccione la ubicación de destino para los artículos recibidos" -#: order/serializers.py:808 +#: order/serializers.py:863 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:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Fecha de Expiración" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Introduzca números de serie para artículos de almacén entrantes" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Código de barras escaneado" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Código de barras en uso" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Se deben proporcionar las partidas" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Se requiere ubicación de destino" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Los valores del código de barras deben ser únicos" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Envíos" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Envíos completados" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Moneda del precio de venta" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Elementos asignados" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "No se proporcionaron detalles de envío" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "La cantidad debe ser positiva" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Introduzca números de serie para asignar" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "El envío ya ha sido enviado" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "El envío no está asociado con este pedido" -#: order/serializers.py:1777 +#: 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:1784 +#: 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:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Partida de orden de devolución" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "La partida no coincide con la orden de devolución" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "La partida ya ha sido recibida" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Cantidad a devolver" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Moneda de precio de línea" @@ -5598,146 +5742,150 @@ msgstr "Reembolso" msgid "Reject" msgstr "Rechazo" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Orden de compra atrasada" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "La orden de compra {po} está atrasada" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Orden de venta atrasada" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La orden de venta {so} está atrasada" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Favoritos" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Profundidad" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtrar por profundidad de categoría" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Nivel superior" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtrar por categorías de nivel superior" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "En cascada" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Tiene resultados" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Categoría de parte" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Categorías de parte" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Ubicación Predeterminada" @@ -5778,7 +5926,7 @@ msgstr "Palabras clave por defecto para partes en esta categoría" msgid "Icon" msgstr "Icono" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Icono (opcional)" @@ -5799,1025 +5947,1050 @@ msgstr "Valor predeterminado" msgid "Default Parameter Value" msgstr "Valor de parámetro por defecto" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Partes" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN duplicado no permitido en la configuración de partes" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "La revisión de parte duplicada ya existe." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Parte con este nombre, IPN y revisión ya existe." -#: part/models.py:1075 +#: part/models.py:1070 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:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nombre de la parte" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Es plantilla" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "¿Es esta parte una parte de la plantilla?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Descripción de parte (opcional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Palabras claves" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Categoría de parte" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Revisión de parte o número de versión" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisión" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Variante de" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "¿Dónde se almacena este artículo normalmente?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Expiración por defecto" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Stock mínimo" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Nivel mínimo de stock permitido" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Unidades de medida para esta parte" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "¿Se puede construir esta parte a partir de otras partes?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "¿Se puede utilizar esta parte para construir otras partes?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "¿Esta parte tiene seguimiento de objetos únicos?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "¿Se puede comprar esta parte a proveedores externos?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "¿Se puede vender esta parte a los clientes?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "¿Está activa esta parte?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Las partes bloqueadas no pueden ser editadas" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Suma de verificación de BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Suma de verificación de BOM almacenada" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM comprobado por" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Fecha BOM comprobada" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Creación de Usuario" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Dueño responsable de esta parte" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Vender múltiples" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Moneda utilizada para almacenar en caché los cálculos de precios" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Costo mínimo de BOM" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Costo mínimo de partes de componentes" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Costo máximo de BOM" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Costo máximo de partes de componentes" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Costo mínimo de compra" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Costo histórico mínimo de compra" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Costo máximo de compra" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Costo histórico máximo de compra" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Precio interno mínimo" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Costo mínimo basado en precios reducidos internos" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Precio interno máximo" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Costo máximo basado en precios reducidos internos" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Precio mínimo de proveedor" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Precio mínimo de la parte de proveedores externos" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Precio máximo de proveedor" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Precio máximo de la parte de proveedores externos" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Costo mínimo de variante" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Costo mínimo calculado de las partes variantes" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Costo máximo de variante" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Costo máximo calculado de las partes variantes" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Costo mínimo" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Anular el costo mínimo" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Costo máximo" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Reemplazar coste máximo" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Costo mínimo general calculado" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Precio de venta mínimo" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Precio de venta mínimo basado en precios reducidos" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Precio de venta máximo" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Precio de venta máximo basado en precios reducidos" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Costo de venta mínimo" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Precio de venta mínimo histórico" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Costo de Venta Máximo" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Precio de venta máximo histórico" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Número de artículos" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Fecha" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Costo de Stock Mínimo" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Costo mínimo estimado del stock disponible" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nombre de prueba" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Introduzca un nombre para la prueba" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Descripción de prueba" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Introduce la descripción para esta prueba" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Requerido" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "¿Es necesario pasar esta prueba?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Requiere valor" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Adjunto obligatorio" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Seleccionar parte principal" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sub parte" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Seleccionar parte a utilizar en BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Cantidad del artículo en BOM" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Este artículo BOM es opcional" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Referencia de artículo de BOM" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notas del artículo de BOM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Suma de verificación" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Suma de verificación de línea de BOM" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validado" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Este artículo de BOM ha sido validado" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "La cantidad debe ser un valor entero para las partes rastreables" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Debe especificar la subparte" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Ítem de BOM sustituto" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Artículo BOM superior" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Sustituir parte" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Seleccionar parte relacionada" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Nota para esta relación" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Categoría principal de parte" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Subcategorías" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Moneda de compra de ítem de stock" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Parte original" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Seleccione la parte original a duplicar" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Copiar Imagen" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Copiar imagen desde la parte original" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copiar BOM" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Copiar Parámetros" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Copiar datos del parámetro de la parte original" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Copiar Notas" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Cantidad Inicial de Stock" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Seleccione proveedor (o déjelo en blanco para saltar)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleccionar fabricante (o dejar en blanco para saltar)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Número de parte del fabricante" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "La empresa seleccionada no es un proveedor válido" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "La empresa seleccionada no es un fabricante válido" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Nombre de categoría" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "En construcción" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Elementos de stock" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Inventario Total" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Duplicar Parte" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Stock Inicial" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Crear Parte con cantidad inicial de stock" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Información del proveedor" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Añadir información inicial del proveedor para esta parte" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Copiar Parámetros de Categoría" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Copiar plantillas de parámetro de la categoría de partes seleccionada" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Imagen Existente" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "El archivo de imagen no existe" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Validación de Lista de Materiales" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Puede construir" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Precio mínimo" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Anular el valor calculado para precio mínimo" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Precio mínimo de moneda" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Precio máximo" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Precio máximo de moneda" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Actualizar" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Seleccionar parte de la que copiar BOM" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Eliminar Datos Existentes" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Eliminar artículos BOM existentes antes de copiar" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Incluye Heredado" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Omitir filas no válidas" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Activar esta opción para omitir filas inválidas" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Copiar partes sustitutas" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notificación por bajo stock" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "Impresión de etiquetas fallida" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "Proporciona soporte nativo para códigos de barras" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Impresora de etiquetas PDF de InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Proporciona soporte nativo para imprimir etiquetas PDF" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Modo de depuración" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activar modo de depuración - devuelve código HTML en lugar de PDF" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "El complemento no está instalado" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Instalación del complemento no encontrada" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Complemento" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "No se encontró autor" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "El complemento requiere al menos la versión {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "El complemento requiere como máximo la versión {v}" @@ -7884,55 +8070,55 @@ msgstr "Instalación no confirmada" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Activar complemento" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Activar este complemento" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "Dimensiones de etiqueta inválidas" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "Carta" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nombre de la plantilla" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Adjuntar al modelo al imprimir" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Patrón de Nombre de archivo" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtros" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Tamaño de página para reportes PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Ancho [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Ancho de la etiqueta, especificado en mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Altura de la etiqueta, especificada en mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Fragmento" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Archivo fragmento de informe" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Descripción de archivo de fragmento" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Activo" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Reportar archivo de activos" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Descripción del archivo de activos" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Selecciona la plantilla de etiqueta" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Complemento de impresión" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Selecciona el complemento a usar para imprimir etiquetas" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de serie" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Elementos instalados" @@ -8248,184 +8438,196 @@ msgstr "Ningún resultado (requerido)" msgid "No result" msgstr "Sin resultados" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Ubicación principal" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtrar por ubicación principal" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Nombre de pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "El nombre de la pieza contiene (insensible a mayúsculas y minúsculas)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Nombre de la pieza (expresión regular)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "IPN de Pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "IPN de pieza contiene (insensible a mayúsculas y minúsculas)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "IPN de Pieza (expresión regular)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Existencias mínimas" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Existencias máximas" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Código de estado" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Ubicación externa" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Consumido por orden de construcción" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Instalado en otro artículo de existencias" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Árbol de piezas" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Actualizado antes de" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Actualizado después de" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Inventario antes de" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Inventario después de" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Desactualizado" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Cantidad requerida" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Debe suministrarse una parte válida" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Ubicación de Stock" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Ubicaciones de Stock" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Propietario" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Seleccionar Propietario" @@ -8461,7 +8663,7 @@ msgstr "Seleccionar Propietario" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Externo" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Se debe especificar la pieza" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "El objeto no puede pertenecer a sí mismo" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Artículo de stock padre" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Parte base" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "¿Dónde se encuentra este artículo de stock?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Empaquetar este artículo de stock se almacena en" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Instalado en" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "¿Está este artículo instalado en otro artículo?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Número de serie para este artículo" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Código de lote para este artículo de stock" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Cantidad de Stock" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Build de origen" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Build para este item de stock" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Orden de compra de origen" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Orden de compra para este artículo de stock" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Orden de venta de destino" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Eliminar al agotar" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Eliminar este artículo de stock cuando se agoten las existencias" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Precio de compra único en el momento de la compra" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Convertido a parte" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "La parte no está establecida como rastreable" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Cantidad debe ser un entero" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Los números de serie deben ser proporcionados como una lista" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "La cantidad no coincide con los números de serie" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 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:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Artículo de stock está instalado en otro artículo" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Artículo de stock contiene otros artículos" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Artículo de stock ha sido asignado a un cliente" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "El artículo de stock está en producción" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Stock serializado no puede ser combinado" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Artículos de Stock Duplicados" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Los artículos de stock deben referirse a la misma parte" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Los códigos de estado del stock deben coincidir" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Notas de entrada" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Debe proporcionarse un valor para esta prueba" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "El archivo adjunto debe ser subido para esta prueba" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Resultado de la prueba" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Valor de salida de prueba" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Adjunto de resultados de prueba" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Notas de prueba" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Finalizó" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Elemento padre" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Introduzca números de serie para nuevos artículos" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Número de pieza del proveedor" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Elementos secundarios" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Introduzca el número de artículos de stock para serializar" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Ubicación de stock de destino" -#: stock/serializers.py:735 +#: stock/serializers.py:760 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:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Números de serie ya existen" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Añadir nota de transacción (opcional)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sub-ubicación" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "La parte debe ser vendible" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "El artículo está asignado a una orden de venta" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "El artículo está asignado a una orden de creación" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Cliente para asignar artículos de stock" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "La empresa seleccionada no es un cliente" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Notas de asignación de stock" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Debe proporcionarse una lista de artículos de stock" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notas de fusión de stock" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Permitir proveedores no coincidentes" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Permitir estado no coincidente" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Debe proporcionar al menos dos artículos de stock" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Sin cambios" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Valor de clave primaria de Stock" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "No hay existencias del artículo" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Notas de transacción de stock" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Última vez que se usó el token" msgid "Revoked" msgstr "Revocado" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Permiso establecido" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Vista" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Permiso para ver artículos" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Añadir" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Permiso para añadir artículos" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Cambiar" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Permisos para editar artículos" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Eliminar" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Permiso para eliminar artículos" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Ordenes de compra" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Órdenes de venta" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Ordenes de devolución" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nombre de usuario" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Nombre" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Nombre del usuario" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Apellido" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Apellido del usuario" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Dirección de correo del usuario" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personal" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Tiene este usuario permisos de personal" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superusuario" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Es este usuario un superusuario" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Esta cuenta de usuario está activa" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Su cuenta ha sido creada." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 2bbbdcea24..ac5f2ae637 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Estonian\n" "Language: et_EE\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Teil ei ole selle lehe vaatamiseks luba" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "" @@ -112,13 +105,13 @@ msgstr "Pane kuupäev" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Märkmed" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Ühenduse viga" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Esines tõrge" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-post" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Vigane valik" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nimi" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Kirjeldus" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Kirjeldus (valikuline)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Tee" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serveri viga" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Hiina (lihtsustatud)" msgid "Chinese (Traditional)" msgstr "Hiina (traditsiooniline)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Osa" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Määratud" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Valikuline" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Jälgitud" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Asukoht" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "Tootekood" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Koostamise olek" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Loomise kuupäev" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Kogus" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Osa nimi" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Tühista kõik laoseisu eraldised mahakantud väljundite jaoks" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Valikained" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Jälgitav" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Saadaval laos" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Katkestatud" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Valmis" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "On link" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "On fail" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "Pluginat pole" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Uuendatud" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Seade võti" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Seade väärtus" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Pealkiri" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Avaldatud" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Kokkuvõte" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Loetud" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Pildifail" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Ühiku nimi" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Sümbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definitsioon" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Ühiku definitsioon" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Manus" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Puuduv fail" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Puuduv väline link" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Vali fail, mida lisada" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentaar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Faili suurus" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Silt" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Loodud" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Mall" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Andmed" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Märkus" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Vöötkoodi andmed" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Vastus" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Tulemus" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Võti" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Ülesande nimi" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funktsioon" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funktsiooni nimi" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumendid" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Ülesande argumendid" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Failinimi" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Mudeli liik" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Grupp puudub" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Taaskäivitamine on vajalik" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Ettevõtte nimi" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "päeva" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automaatne varundus" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Vöötkoodi tugi" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Ostetav" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuaalne" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: 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:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" -msgstr "Luba liidese integreerimine" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" +msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" -msgstr "Luba pluginatel integreeruda kasutajaliidesesse" +msgid "Enable navigation integration" +msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: common/setting/system.py:1105 +msgid "Enable plugins to respond to internal events" msgstr "" +#: common/setting/system.py:1111 +msgid "Enable interface integration" +msgstr "Luba liidese integreerimine" + #: common/setting/system.py:1112 -msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgid "Enable plugins to integrate into the user interface" +msgstr "Luba pluginatel integreeruda kasutajaliidesesse" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Tootja" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Ettevõte" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Laos" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Ettevõtted" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Ettevõtte kirjeldus" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Ettevõtte kirjeldus" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Veebileht" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Ettevõtte veebilehe aadress" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefoninumber" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kontakttelefoni number" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontakt e-postiaadress" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Aadress" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Aadressid" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Vali ettevõte" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Peamine aadress" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Määra peamine aadress" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Rida 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Aadressi rida 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Rida 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Aadressi rida 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Postiindeks" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Linn/Piirkond" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Riik" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tarnija" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Vali tarnija" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Väli" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Veerg" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupp" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Staatus" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Müügihind" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Saadetud" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Saadetis" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Rida" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Tellimuse ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "Kopeeritava tellimuse ID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Kopeeri read" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Kopeeri reaüksused algsest tellimusest" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Kopeeri lisareaüksused algsest tellimusest" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Määrake selle tellimuse dubleerimise valikud" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Vale tellimuse ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Tootekood" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Vöötkood" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Skännitud ribakood" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Saadetised" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Järgmised seerianumbrid ei ole saadaval" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "Tagasimakse" msgid "Reject" msgstr "Keeldu" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Sügavus" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Osa kategooria" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Osa kategooriad" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "Ikoon" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikoon (valikuline)" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Osad" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Osa nimi" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "On mall" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Märksõnad" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Osa kategooria" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimaalne laoseis" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Testimalle saab luua ainult testitavate osade jaoks" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Originaalosa" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopeeri pilt" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Kopeeri parameetrid" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategooria nimi" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Ehitamine" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Tarnija info" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimaalne hind" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maksimaalne hind" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Uuenda" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "Piirjoon" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "Paki plugin" msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Autorit ei leitud" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Lisa mudelile printimisel" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtrid" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Mallifaili" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seerianumber" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Testitulemused" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Tarnija osa number" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "Tühistatud" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Vaade" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Muuda" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Kustuta" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Kasutajanimi" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Eesnimi" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Perekonnanimi" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 35bf387287..5bda507b9e 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Persian\n" "Language: fa_IR\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Address e API peida nashod" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "لیست اقلام یا فیلترها باید برای عملیات انبوه ارائه شود" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "موارد باید به صورت لیست ارائه شود" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "لیست موارد نامعتبر ارائه شده است" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "فیلترها باید به صورت دستوری ارائه شوند" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "فیلترهای نامعتبر ارائه شده است" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "تمامی فیلترها باید منحصراً با مقدار true مورد استفاده قرار گیرند" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "هیچ موردی با معیارهای ارائه شده مطابقت ندارد" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "کاربر سطح دسترسی نمایش این مدل را ندارد" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "نمی‌توان {original} را به {unit} تبدیل کرد" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "مقدار ارائه شده نامعتبر است" @@ -112,13 +105,13 @@ msgstr "تاریخ را وارد کنید" msgid "Invalid decimal value" msgstr "مقدار اعشاری نامعتبر است" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "یادداشت" @@ -131,75 +124,91 @@ msgstr "مقدار '{name}' در قالب الگو ظاهر قرار نمی گی msgid "Provided value does not match required pattern: " msgstr "مقدار ارائه شده با الگوی مورد نیاز مطابقت ندارد: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "نمی توان بیش از 1000 مورد را به طور همزمان سریال کرد" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "رشته شماره سریال خالی" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "سریال تکراری" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "گروه نامعتبر: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "محدوده گروه {group} از مقدار مجاز بیشتر است ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "هیچ شماره سریالی پیدا نشد" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "برچسب های HTML را از این مقدار حذف کنید" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "داده ها حاوی محتوای علامت گذاری ممنوع است" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "خطا در اتصال" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "سرور با کد وضعیت نامعتبر پاسخ داد" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "یک استثنا رخ داده است" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "سرور با مقدار طول محتوا نامعتبر پاسخ داد" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "اندازه عکس بسیار بزرگ است" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "حجم دانلود تصویر از حداکثر اندازه بیشتر شده است" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "سرور ریموت پاسخ خالی را برگرداند" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "URL ارائه شده یک فایل تصویری معتبر نیست" @@ -207,11 +216,11 @@ msgstr "URL ارائه شده یک فایل تصویری معتبر نیست" msgid "Log in to the app" msgstr "وارد برنامه شوید" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "ایمیل" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "قبل از انجام هر کار دیگری باید احراز هویت دو مرحله ای را فعال کنید." @@ -255,133 +264,108 @@ msgstr "مرجع باید با الگوی مورد نیاز مطابقت داش msgid "Reference number is too large" msgstr "شماره مرجع خیلی بزرگ است" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "انتخاب نامعتبر" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "نام" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "توضیحات" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "توضیحات (اختیاری)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "مسیر" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "نام‌های تکراری نمی‌توانند تحت یک والد وجود داشته باشند" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "یادداشت های علامت گذاری (اختیاری)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "داده های بارکد" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "داده های بارکد شخص ثالث" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "هش بارکد" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "هش منحصر به فرد داده های بارکد" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "بارکد موجود پیدا شد" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "شکست کار" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "پس از {n} تلاش، کار پس زمینه '{f}' ناموفق بود" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "خطای سرور" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "یک خطا توسط سرور ثبت شده است." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "باید یک عدد معتبر باشد" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "ارز" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "ارز را از گزینه های موجود انتخاب کنید" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "مقدار نامعتبر" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "تصویر ریموت" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "آدرس فایل تصویری از راه دور" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "دانلود تصاویر از URL ریموت فعال نیست" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "دانلود تصویر از URL ریموت انجام نشد" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "چینی (ساده شده)" msgid "Chinese (Traditional)" msgstr "چینی (سنتی)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "واحد فیزیکی نامعتبر" msgid "Not a valid currency code" msgstr "کد ارز معتبر" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "وضعیت سفارش" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "قطعه" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "دسته" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "واگذار شده به من" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "واگذار شده به" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "ایجاد شده قبل از" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "ایجاد شده بعد از" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "دارای تاریخ شروع" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "تاریخ شروع قبل از" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "تاریخ شروع بعد از" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "دارای تاریخ موعد" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "تاریخ موعد قبل از" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "تاریخ موعد بعد از" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "تکمیل شده قبل از" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "تکمیل شده بعد از" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "مصرفی" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "اختیاری" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "مونتاژ" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "سفارش معوق" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "اختصاص داده شده" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "سفارش ساخت" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "مکان" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "سفارش‌های ساخت" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "مرجع سفارش فروش" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "منبع محل" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "مقصد" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "تاریخ تکمیل" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "تکمیل شده توسط" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "صادر شده توسط" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "کاربری که این سفارش ساخت را صادر کرده است" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "پیوند خارجی" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 c17488875c..d2c4c54d3a 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API-rajapintaa ei löydy" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Käyttäjän oikeudet eivät riitä kohteen tarkastelemiseen" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Annettu määrä on virheellinen" @@ -112,13 +105,13 @@ msgstr "Anna päivämäärä" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Merkinnät" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Tyhjä sarjanumero" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplikaatti sarjanumero" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Sarjanumeroita ei löytynyt" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Yhteysvirhe" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Palvelin vastasi virheellisellä tilakoodilla" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Kuva on liian iso" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Kuvan lataus ylitti enimmäiskoon" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Etäpalvelin palautti tyhjän vastauksen" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Annettu URL ei ole kelvollinen kuvatiedosto" @@ -207,11 +216,11 @@ msgstr "Annettu URL ei ole kelvollinen kuvatiedosto" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Sähköposti" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "Viitenumero on liian suuri" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Virheellinen valinta" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nimi" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Kuvaus" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Kuvaus (valinnainen)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Polku" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Viivakoodin Tiedot" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Palvelinvirhe" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Täytyy olla kelvollinen luku" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuutta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Valitse valuutta käytettävissä olevista vaihtoehdoista" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Virheellinen arvo" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Kuvatiedoston URL" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Kuvien lataaminen ei ole käytössä" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Osa" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategoria" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Sijainti" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Ulkoinen linkki" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Linkki ulkoiseen URLiin" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Määrä" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Varastotuote" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Sarjanumerot" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Ei sallittu" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Seurattavissa" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Peruttu" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Valmis" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Päivitetty" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Viimeisimmän päivityksen aikaleima" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Käyttäjä" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Hinta" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktiivinen" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Salaisuus" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Isäntä" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Otsikko" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Linkki" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Julkaistu" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Julkaisija" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Yhteenveto" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Kuvatiedosto" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Liite" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Puuttuva tiedosto" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Puuttuva ulkoinen linkki" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Valitse liitettävä tiedosto" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentti" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Arvo" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Käytössä" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Muistiinpano" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Avain" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Tiedostonimi" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Ei ryhmää" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Uudelleenkäynnistys vaaditaan" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Yrityksen nimi" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Yrityksen sisäinen nimi" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Oletusvaluutta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "päivää" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automaattinen varmuuskopionti" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Ota käyttöön tietokannan ja mediatiedostojen automaattinen varmuuskopiointi" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automaattisen varmuuskopioinnin aikaväli" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Viivakoodituki" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponentti" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Ostettavissa" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Sisäiset hinnat" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Sisäisen hinnan ohitus" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: 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:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "Salli salasananpalautus" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" -msgstr "Salli rekisteröinti" - -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" -msgstr "Salli SSO" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" +msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "Salli SSO kirjautumissivuilla" +#: common/setting/system.py:938 +msgid "Convert Currency" +msgstr "" -#: common/setting/system.py:942 -msgid "Enable SSO registration" -msgstr "Salli SSO rekisteröinti" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" +msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" +#: common/setting/system.py:953 +msgid "Enable password forgot" +msgstr "Salli salasananpalautus" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +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:964 -msgid "SSO group map" -msgstr "" +#: common/setting/system.py:965 +msgid "Enable SSO" +msgstr "Salli SSO" #: common/setting/system.py:966 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +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:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:974 -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:980 -msgid "Email required" -msgstr "Sähköposti vaaditaan" - #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +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 "" + +#: 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" +msgstr "" + +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Sähköpostiosoite kahdesti" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Salasana kahdesti" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Sallitut verkkotunnukset" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Pakota MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "" -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Valmistaja" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Yritys" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Yritykset" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Yrityksen kuvaus" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Sivusto" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Yrityksen sivuston URL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Puhelinnumero" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakti" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Osoite" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Valitse valmistaja" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Valmistajan osanumero" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Toimittaja" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Valitse toimittaja" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Toimittajan varastonimike" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Valitse valmistajan osa" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Ryhmä" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Valmis" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Hinta yhteensä" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Tilauksen valuutta" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Tilauksen viite" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Tila" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Asiakas" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Asiakkaan viite " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "Vastaanotettu" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Lähetetty" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Seurantakoodi" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Laskunumero" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Viivakoodi" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "Kuvake" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Kuvake (valinnainen)" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Avainsanat" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Päivämäärä" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Valmistajan osanumero" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Suodattimet" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Leveys [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Korkeus [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sarjanumero" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Näytä" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Oikeus tarkastella kohteita" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Oikeus lisätä kohteita" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Muuta" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Oikeus muokata kohteita" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Poista" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Oikeus poistaa kohteita" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Käyttäjätunnus" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Etunimi" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Sukunimi" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 8c7f10b22a..55d8b2aaf4 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Point de terminaison de l'API introuvable" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Liste des éléments ou des filtres à fournir pour les opérations en vrac" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Les éléments doivent être fournis sous forme de liste" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Liste d'éléments non valide fournie" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Les filtres doivent être fournis sous forme de dictionnaire" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtres fournis invalides" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Tous les filtres ne doivent être utilisés qu'avec \"true\"" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Aucun élément ne correspond aux critères fournis" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Aucune donnée disponible" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Ce champ doit être unique" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "L'utilisateur n'a pas la permission de voir ce modèle" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Quantité fournie invalide" @@ -112,13 +105,13 @@ msgstr "Entrer la date" msgid "Invalid decimal value" msgstr "Valeur décimale invalide" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notes" @@ -131,75 +124,91 @@ msgstr "La valeur '{name}' n'apparaît pas dans le format du modèle" msgid "Provided value does not match required pattern: " msgstr "La valeur fournie ne correspond pas au modèle requis : " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Impossible de sérialiser plus de 1000 éléments à la fois" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Chaîne de numéro de série vide" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Numéro de série en doublon" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Groupe invalide : {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Aucun numéro de série trouvé" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Retirer les balises HTML de cette valeur" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Les données contiennent du contenu markdown interdit" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Erreur de connexion" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Le serveur a répondu avec un code de statut invalide" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Une erreur est survenue" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Image trop volumineuse" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "La taille de l'image dépasse la taille maximale autorisée" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Le serveur distant a renvoyé une réponse vide" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "L'URL fournie n'est pas un fichier image valide" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Vous devez activer l'authentification à deux facteurs avant toute autre chose." @@ -255,133 +264,108 @@ msgstr "La référence doit correspondre au modèle requis" msgid "Reference number is too large" msgstr "Le numéro de référence est trop grand" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Choix invalide" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nom" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Description" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Description (facultative)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Chemin d'accès" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 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:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notes Markdown (option)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Données du code-barres" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Données de code-barres tierces" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash du code-barre" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hachage unique des données du code-barres" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Code-barres existant trouvé" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Échec de la tâche" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "La tâche de travail en arrière-plan '{f}' a échoué après {n} tentatives" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Erreur serveur" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Une erreur a été loguée par le serveur." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Doit être un nombre valide" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Devise" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Sélectionnez la devise à partir des options disponibles" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Ce champ ne peut pas être vide." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valeur non valide" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Images distantes" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL du fichier image distant" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Le téléchargement des images depuis une URL distante n'est pas activé" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Échec du téléchargement de l'image à partir de l'URL distant" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Format du type de contenu invalide" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Type de contenu introuvable" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Le type de contenu ne correspond pas à la classe de mixin requise" @@ -537,11 +521,11 @@ msgstr "Chinois (Simplifié)" msgid "Chinese (Traditional)" msgstr "Chinois (Traditionnel)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Mise à jour disponible" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Une mise à jour pour InvenTree est disponible" @@ -553,30 +537,30 @@ msgstr "Unité invalide" msgid "Not a valid currency code" msgstr "Code de devise invalide" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Statut de la commande" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Fabrication parente" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Inclure les variantes" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Inclure les variantes" msgid "Part" msgstr "Pièce" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Catégorie" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Version Précédente" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Attribué à moi" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Attribué à" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Créé avant" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Créé après" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "A une date de début" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Date de début avant" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Date de début après" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "A une date butoir" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Date cible avant" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Date cible après" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Terminé avant" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Terminé après" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Date min" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Date maximale" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Exclure l'arbre" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consommable" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Facultatif" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Assemblage" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Suivi" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testable" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Commande en cours" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Allouée" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Consommé" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "En Commande" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordre de Fabrication" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Emplacement" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Sortie" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Ordres de Fabrication" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "La liste des composants de l'assemblage n'a pas été validée" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Un utilisateur ou un groupe responsable doit être spécifié" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "La pièce de commande de construction ne peut pas être changée" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "La date cible doit être postérieure à la date de début" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Référence de l' Ordre de Fabrication" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Référence de l' Ordre de Fabrication" msgid "Reference" msgstr "Référence" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Brève description de la fabrication (optionnel)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "Commande de fabrication associée à cette fabrication" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Sélectionnez la pièce à construire" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Bon de commande de référence" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Commande de vente à laquelle cette fabrication est allouée" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Emplacement d'origine" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Fabrication externe" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Cet ordre de fabrication est exécuté en externe" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Emplacement cible" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Quantité a fabriquer" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Nombre de stock items à construire" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Articles terminés" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Nombre d'articles de stock qui ont été terminés" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "État de la construction" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Code de statut de construction" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Code de lot" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Code de lot pour ce build output" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Date de création" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Début de la fabrication" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Date de début prévue pour cet ordre de construction" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Date d'achèvement cible" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Date d'achèvement" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "achevé par" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Émis par" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Utilisateur ayant émis cette commande de construction" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Utilisateur ou groupe responsable de cet ordre de construction" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Lien Externe" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Lien vers une url externe" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Priorité de fabrication" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Priorité de cet ordre de fabrication" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Code du projet" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Code de projet pour cet ordre de construction" -#: build/models.py:686 +#: build/models.py:697 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:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Impossible de terminer l'ordre de fabrication avec des sorties incomplètes" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Une commande de construction a été effectuée" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Pas d'ordre de production défini" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "L'ordre de production a déjà été réalisé" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "L'ordre de production de correspond pas à l'ordre de commande" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "La quantité doit être supérieure à zéro" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 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:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "Les articles en stock alloués sont toujours en production" -#: build/models.py:1208 +#: build/models.py:1221 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:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Poste de l'ordre de construction" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Création de l'objet" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantité" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Quantité requise pour la commande de construction" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Quantité de stock consommé" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "La quantité allouée doit être supérieure à zéro" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "La quantité doit être de 1 pour stock sérialisé" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "L'article de stock est suralloué" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Article en stock" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Stock d'origine de l'article" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Quantité de stock à allouer à la construction" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Installer dans" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Stock de destination de l'article" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Niveau de construction" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nom de l'article" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Sortie d'assemblage" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "L'ordre de production ne correspond pas à l'ordre parent" -#: build/serializers.py:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Cet ordre de production a déjà été produit" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Cet ordre de production n'est pas complètement attribué" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Entrer la quantité désiré pour la fabrication" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Quantité entière requise pour les pièces à suivre" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Numéros de série" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Entrer les numéros de séries pour la fabrication" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Emplacement de stock pour la sortie de la fabrication" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Allouer automatiquement les numéros de série" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Une liste d'ordre de production doit être fourni" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Emplacement du stock pour les sorties épuisées" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Ignorer les allocations" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Abandonner les allocations de stock pour les sorties abandonnées" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Motif de l'élimination des produits de construction(s)" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Emplacement des ordres de production achevés" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Accepter l'allocation incomplète" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consommation du stock alloué" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Retirer les sorties incomplètes" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Non permis" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Accepter comme consommé par cet ordre de construction" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Désaffecter avant de terminer cette commande de fabrication" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Stock suralloué" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Certains articles de stock ont été suralloués" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Accepter les non-alloués" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Le stock requis n'a pas encore été totalement alloué" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Accepter les incomplèts" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "La quantité nécessaire n'a pas encore été complétée" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "L'ordre de construction a des ordres de construction enfants ouverts" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "L'ordre de construction doit être en état de production" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "L'ordre de production a des sorties incomplètes" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Chaîne d'assemblage" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Sortie d'assemblage" -#: build/serializers.py:879 +#: build/serializers.py:885 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:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Élément de la ligne de construction" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "L'article doit être en stock" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Les articles d'allocation doivent être fournis" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Emplacements exclus" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Exclure les articles de stock de cet emplacement sélectionné" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Stock interchangeable" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Stock de substitution" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Autoriser l'allocation de pièces de remplacement" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Objets Optionnels" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Affecter des éléments de nomenclature facultatifs à l'ordre de fabrication" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Échec du démarrage de la tâche d'auto-allocation" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Référence de la nomenclature" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID de la pièce de la nomenclature" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nomenclature Nom de la pièce" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Construire" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Pièce fournisseur" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Quantité allouée" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Référence de construction" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Nom de la catégorie de pièces" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Traçable" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Reçu de quelqu'un" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Autoriser les variantes" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Article du BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "En Production" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Planifié pour fabrication" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Stock externe" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Stock disponible" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Stock de substitution disponible" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Stock de variantes disponibles" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "La quantité consommée dépasse la quantité allouée" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Note optionnelle pour la consommation du stock" -#: build/serializers.py:1806 +#: build/serializers.py:1807 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:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Dupliquer l'allocation de l'article de fabrication" -#: build/serializers.py:1829 +#: build/serializers.py:1830 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:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Dupliquer l'allocation de ligne de fabrication" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Au moins un élément ou une ligne doit être fourni" @@ -1495,43 +1479,47 @@ msgstr "En pause" msgid "Cancelled" msgstr "Annulé" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Terminé" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Stock requis pour la commande de construction" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "L'ordre de fabrication {build} nécessite du stock additionnel" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Ordre de commande en retard" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "L'ordre de commande {bo} est maintenant en retard" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "C'est un lien" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "C'est un fichier" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "L'utilisateur n'a pas les permissions de supprimer cette pièce jointe" @@ -1551,798 +1539,822 @@ msgstr "Aucun code de devise valide fourni" msgid "No plugin" msgstr "Pas de plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Code du projet Étiquette" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Mise à jour" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Date de la dernière mise à jour" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Mis à jour par" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Utilisateur qui a mis à jour cet objet en dernier" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Code projet unique" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Description du projet" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Utilisateur ou groupe responsable de ce projet" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Paramétrés des touches" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valeur du paramètre" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "La valeur doit être une valeur booléenne" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "La valeur doit être un nombre entier" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Valeur doit être un nombre valide" -#: common/models.py:893 +#: 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:915 +#: 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:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Utilisateur" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Quantité de rupture de prix" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Prix" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Prix unitaire à la quantité spécifiée" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Point final" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nom de ce webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Actif" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Ce webhook (lien de rappel HTTP) est-il actif" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Jeton" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Jeton d'accès" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Confidentiel" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Secret partagé pour HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID message" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identifiant unique pour ce message" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Hôte" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Hôte à partir duquel ce message a été reçu" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Entête" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "En-tête de ce message" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Corps" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Corps de ce message" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endpoint à partir duquel ce message a été reçu" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Travaillé sur" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Le travail sur ce message est-il terminé ?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titre" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Lien" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publié" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Auteur" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Résumé" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Lu" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Cette nouvelle a-t-elle été lue ?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Fichier image" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Type de modèle cible pour cette image" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "ID du modèle cible pour cette image" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Unité personnalisée" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Le symbole de l'unité doit être unique" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Le nom de l'unité doit être un identifiant valide" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nom de l'unité" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbole" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Symbole d'unité facultatif" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Définition" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Définition de l'unité" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Pièce jointe" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Fichier manquant" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Lien externe manquant" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Type de modèle" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Type de modèle cible pour l'image" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Sélectionnez un fichier à joindre" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Commentaire" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Commentaire sur la pièce jointe" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Date de téléchargement" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Date de téléchargement du fichier" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Taille du fichier" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Taille du fichier en octets" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Type de modèle non valide spécifié pour la pièce jointe" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "État personnalisé" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "États membres de l'Union européenne" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Ensemble d'états de référence" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Ensemble d'états étendu à cet état personnalisé" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Clé logique" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valeur" -#: common/models.py:2114 +#: common/models.py:2196 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:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Nom de l'Etat" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Étiquette" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiquette qui sera affichée dans le frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Couleur" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Couleur qui sera affichée dans le frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modèle" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Modèle cet état est associé à" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Le modèle doit être sélectionné" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "La clé doit être sélectionnée" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "La clé logique doit être sélectionnée" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "La clé doit être différente de la clé logique" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Une classe de statut de référence valide doit être fournie" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Liste de sélection" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Listes de sélection" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Nom de la liste de sélection" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Description de la liste de sélection" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Verrouillé" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Cette liste de sélection est-elle verrouillée ?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Cette liste de sélection peut-elle être utilisée ?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Plug-in source" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Plugin qui fournit la liste de sélection" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Chaîne source" -#: common/models.py:2280 +#: common/models.py:2362 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:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Entrée par défaut" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Entrée par défaut pour cette liste de sélection" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Créé le" -#: common/models.py:2296 +#: common/models.py:2378 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:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Dernière mise à jour" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Entrée de la liste de sélection" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Entrées de la liste de sélection" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Liste de sélection à laquelle appartient cette entrée" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Valeur de l'entrée de la liste de sélection" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Étiquette pour l'entrée de la liste de sélection" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Description de l'entrée de la liste de sélection" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Cette entrée de la liste de sélection est-elle active ?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Modèle de paramètre" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Modèle de paramètre" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Les paramètres des cases à cocher ne peuvent pas avoir d'unités" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Les paramètres des cases à cocher ne peuvent pas comporter de choix" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Les choix doivent être uniques" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Le nom du modèle de paramètre doit être unique" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Type de modèle cible pour ce modèle de paramètre" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nom du paramètre" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unités" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Unités physiques pour ce paramètre" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Description des paramètres" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Case à cocher" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Ce paramètre est-il une case à cocher ?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Choix" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Choix valables pour ce paramètre (séparés par des virgules)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Liste de sélection pour ce paramètre" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Activé" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Ce modèle de paramètre est-il activé ?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Paramètre" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Paramètres" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Choix incorrect pour la valeur du paramètre" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Type de modèle non valide pour la pièce jointe" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "Identifiant du Modèle (ID)" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "ID du modèle cible pour ce paramètre" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Modèle" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Modèle de paramètre" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Données" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Valeur du paramètre" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Note" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Champ de notes facultatif" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Analyse du code-barres" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Données du code-barres" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Utilisateur qui a scanné le code-barres" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Horodatage" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Date et heure du scan de code-barres" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Point d'accès à l'URL qui a traité le code-barres" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contexte" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Données contextuelles pour la lecture du code-barres" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Réponse" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Données de réponse provenant de la lecture du code-barres" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Résultat" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "La lecture du code-barres a-t-elle réussi ?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Une erreur s'est produite" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "Message email" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "Messages email" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Annoncé" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Envoyé" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Échec" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Livré" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Confirmé" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Entrant" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Sortant" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Sans réponse" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Suivi de livraison" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Suivi de la lecture" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Suivi du clic" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "ID Global" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID du sujet de discussion" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Fil de discussion" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Fil lié à ce message" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Priorité" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Fil d'Email" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Fils d'Emails" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Clé" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Identifiant unique pour ce fil" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Démarré en interne" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Est-ce que ce fil a été démarré en interne ?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Date et heure de création du fil" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Date et heure de dernière mise à jour du fil" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Articles reçus" @@ -2392,1235 +2404,1303 @@ msgstr "Indique si le paramètre est écrasé par une variable d'environnement" msgid "Override" msgstr "Écraser" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "En cours d'exécution" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Tâches en attente" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tâches planifiées" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tâches échouées" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID de la tâche" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ID unique de la tâche" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Verrouillé" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Heure verrouillé" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nom de la tâche" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Fonction" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nom de la fonction" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Arguments" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Arguments tâche" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Mots-clés Arguments" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Mots-clés arguments tâche" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nom du fichier" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Type de modèle" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: 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:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Pas de groupe" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "L'URL du site est verrouillée par configuration" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Redémarrage nécessaire" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Un paramètre a été modifié, ce qui nécessite un redémarrage du serveur" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migration en attente" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Nombre de migrations de base de données en attente" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Codes warning actifs" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Un dictionnaire de codes d'avertissement actifs" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID de l'instance" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Identifiant unique pour cette instance InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Annoncer l'ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Annoncer l'ID d'instance du serveur dans l'info sur l'état du serveur (non authentifié)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nom de l'instance du serveur" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Chaîne de caractères descriptive pour l'instance serveur" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Utiliser le nom de l'instance" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Utiliser le nom de l’instance dans la barre de titre" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Limiter l'affichage de `about`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Afficher la modale `about` uniquement aux super-utilisateurs" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nom de la société" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nom de société interne" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL de base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL de base pour l'instance serveur" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Devise par défaut" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Sélectionnez la devise de base pour les calculs de prix" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Devises supportées" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Liste des codes de devises supportés" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervalle de mise à jour des devises" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "jours" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Plugin de mise à jour de devise" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Plugin de mise à jour des devises à utiliser" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Télécharger depuis l'URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Autoriser le téléchargement d'images distantes et de fichiers à partir d'URLs externes" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limite du volume de téléchargement" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Taille maximale autorisée pour le téléchargement de l'image distante" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Agent utilisateur utilisé pour télécharger depuis l'URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Permettre de remplacer l'agent utilisateur utilisé pour télécharger des images et des fichiers à partir d'URL externe (laisser vide pour la valeur par défaut)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validation stricte d'URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Spécification du schéma nécessaire lors de la validation des URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Intervalle de vérification des mises à jour" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "À quelle fréquence vérifier les mises à jour (définir à zéro pour désactiver)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Backup automatique" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Activer le backup automatique de la base de données et des fichiers médias" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervalle de sauvegarde automatique" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Spécifiez le nombre de jours entre les sauvegardes automatique" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervalle de suppression des tâches" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Les résultats de la tâche en arrière-plan seront supprimés après le nombre de jours spécifié" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervalle de suppression du journal d'erreur" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Les logs d'erreur seront supprimés après le nombre de jours spécifié" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervalle de suppression du journal de notification" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Les notifications de l'utilisateur seront supprimées après le nombre de jours spécifié" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Intervalle de suppression d'Email" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Les Emails seront supprimés après le nombre de jours spécifié" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Protéger le log d'Email" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Empêcher la suppression des entrées du log d'email" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Support des code-barres" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Activer le support du scanner de codes-barres dans l'interface web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Résultats des codes-barres des magasins" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Stocker les résultats de la lecture du code-barres dans la base de données" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Scanners de codes-barres Comptage maximal" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Nombre maximum de résultats de lecture de codes-barres à stocker" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Délai d'entrée du code-barres" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Délai de traitement du code-barres" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Prise en charge de la webcam code-barres" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Autoriser la numérisation de codes-barres via la webcam dans le navigateur" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Code-barres Afficher les données" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Afficher les données du code-barres dans le navigateur sous forme de texte" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Plugin de génération de codes-barres" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Modifications de la pièce" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Activer le champ de modification de la pièce" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Révision de l'assemblage uniquement" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "N'autoriser les révisions que pour les pièces d'assemblage" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Autoriser la suppression de l'Assemblée" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Autoriser les IPN dupliqués" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permettre à plusieurs pièces de partager le même IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Autoriser l'édition de l'IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copier les données de la pièce" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copier les données des paramètres de la pièce" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copier les données de test de la pièce" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copier les templates de paramètres de catégorie" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Les pièces sont des templates par défaut" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Composant" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Achetable" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Les pièces sont achetables par défaut" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Vendable" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Les pièces sont vendables par défaut" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Les pièces sont traçables par défaut" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuelle" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Les pièces sont virtuelles par défaut" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Afficher les pièces connexes" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Afficher les pièces connexes à une pièce" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Stock initial" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Données initiales du fournisseur" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Format d'affichage du nom de la pièce" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Format pour afficher le nom de la pièce" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Icône de catégorie par défaut" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Nombre minimal de décimales" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Nombre maximal de décimales pour la tarification" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Utiliser le prix fournisseur" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Remplacer l'historique des achats" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Utiliser les prix des articles en stock" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Âge de tarification des articles de stock" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Utiliser les prix variants" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Inclure la tarification variante dans le calcul global des prix" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Variantes actives uniquement" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Mise à jour automatique des prix" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervalle de regénération des prix" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Prix internes" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Activer les prix internes pour les pièces" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Substitution du prix interne" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Activer l'impression d'étiquettes" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Activer l'impression d'étiquettes depuis l'interface Web" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Étiquette image DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Activer les rapports" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Activer la génération de rapports" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Mode Débogage" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Générer des rapports en mode debug (sortie HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Journal des erreurs" -#: common/setting/system.py:668 +#: common/setting/system.py:669 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:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Taille de la page" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Taille de page par défaut pour les rapports PDF" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Renforcer les unités des paramètres" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Numéro de Série Universellement Unique" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Supprimer le stock épuisé" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Modèle de code de lot" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Expiration du stock" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Activer la fonctionnalité d'expiration du stock" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vendre le stock expiré" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Autoriser la vente de stock expiré" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Délai de péremption du stock" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Construction de stock expirée" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Autoriser la construction avec un stock expiré" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Contrôle de la propriété des stocks" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Icône par défaut de l'emplacement du stock" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Afficher les pièces en stock installées" -#: common/setting/system.py:744 +#: common/setting/system.py:757 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:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Vérifier la nomenclature lors de l'installation des articles" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Autoriser le transfert des produits en rupture de stock" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Modèle de référence de commande de construction" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Nécessite un Responsable propriétaire" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Un propriétaire responsable doit être assigné à chaque commande" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Exiger une partie active" -#: common/setting/system.py:778 +#: common/setting/system.py:791 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:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Requiert une pièce verrouillée" -#: common/setting/system.py:784 +#: common/setting/system.py:797 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:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Exiger une nomenclature valide" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Exiger des ordonnances fermées pour les enfants" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Ordres de fabrication externes" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Activer la fonctionnalité d'ordre de fabrication externe" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blocage jusqu'à la réussite des tests" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Activer les retours de commandes" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Modèle de référence de retour de commande" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Modifier les retours de commandes terminées" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Modèle de référence de bon de commande" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Expédition par défaut du bon de commande" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Modifier les commandes de vente terminées" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "L'expédition nécessite une vérification" -#: common/setting/system.py:873 +#: common/setting/system.py:894 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:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Marquer les commandes expédiées comme achevées" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Modèle de référence de commande d'achat" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Modifier les bons de commande terminés" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Convertir la monnaie" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Achat automatique des commandes" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Activer les mots de passe oubliés" -#: common/setting/system.py:925 +#: common/setting/system.py:954 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Activer les inscriptions" -#: common/setting/system.py:931 +#: common/setting/system.py:960 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Activer le SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Activer le SSO sur les pages de connexion" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Activer l'inscription SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Activer la synchronisation du groupe SSO" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Clé du groupe SSO" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Carte de groupe SSO" -#: common/setting/system.py:966 +#: 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 "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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Supprimer les groupes en dehors de SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email requis" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Exiger que l'utilisateur fournisse un mail lors de l'inscription" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Saisie automatique des utilisateurs SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Courriel en double" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Mot de passe deux fois" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Domaines autorisés" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grouper sur inscription" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Forcer l'authentification multifacteurs" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Les utilisateurs doivent utiliser l'authentification multifacteurs." -#: common/setting/system.py:1026 +#: 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 "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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Vérifier les plugins au démarrage" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Vérifier les mises à jour des plugins" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Activer l'intégration d'URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Autoriser les plugins à ajouter des chemins URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Activer l'intégration de navigation" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Activer les plugins à s'intégrer dans la navigation" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Activer l'intégration de plugins" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Activer l'intégration de plugin pour ajouter des apps" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Activer l'intégration du planning" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Autoriser les plugins à éxécuter des tâches planifiées" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Activer l'intégration des évènements" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Autoriser les plugins à répondre aux évènements internes" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Permettre l'intégration de l'interface" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 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:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Activer l'intégration mail" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Autoriser les plugins à traiter les mails entrants/sortants" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Activer les codes de projet" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Activer les codes de projet pour le suivi des projets" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Exclure les localisations externes" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Période de l'inventaire automatique" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Afficher les noms des utilisateurs" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Afficher les profils d'utilisateur" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Afficher les profils des utilisateurs sur leur page de profil" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Activer les données de station de test" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Recevoir des rapports d'erreur" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Recevoir des notifications en cas d'erreurs du système" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Dernières machines d'impression utilisées" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Tous les modèles" @@ -3965,365 +4061,369 @@ msgstr "La pièce est active" msgid "Manufacturer is Active" msgstr "Le fabricant est actif" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Le fournisseur de la pièce est active" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "La pièce interne est active" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Le fournisseur est actif" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabricant" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Société" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "A du stock" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Entreprises" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Description de la société" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Description de la société" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Site web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Site Web de la société" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Numéro de téléphone" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Numéro de téléphone de contact" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Adresse e-mail de contact" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contact" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Point de contact" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Lien externe vers les informations de l'entreprise" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Cette entreprise est-elle active ?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Le client est-il" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Vendez-vous des objets à cette entreprise?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Le fournisseur est-il" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Est-ce que vous achetez des articles à cette entreprise?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Le fabricant est-il" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Cette entreprise fabrique-t-elle des pièces?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Devise par défaut utilisée pour cette entreprise" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "N° de TVA" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "Numéro d'identification fiscale de l'entreprise" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adresse" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adresses" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Sélectionner une entreprise" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Intitulé de l'adresse" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Titre décrivant la saisie de l'adresse" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Adresse principale" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Sélectionner comme adresse principale" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Ligne 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adresse" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Ligne 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Seconde ligne d'adresse" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Code postal" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Ville / Région" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Code postal Ville / Région" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "État / Province" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "État ou province" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Pays" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Pays" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notes du livreur" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Instructions pour le livreur" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Notes pour la livraison interne" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notes internes pour la livraison" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Lien vers les informations de l'adresse (externe)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Pièces du fabricant" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Pièce de base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Sélectionner une partie" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Sélectionner un fabricant" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "Référence fabricant" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Référence du fabricant" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL pour le lien externe de la pièce du fabricant" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Description de la pièce du fabricant" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Les unités d'emballage doivent être supérieures à zéro" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fournisseur" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Sélectionner un fournisseur" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unité de gestion des stocks des fournisseurs" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Cette partie du fournisseur est-elle active ?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Sélectionner un fabricant" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Lien de la pièce du fournisseur externe" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Description de la pièce du fournisseur" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "coût de base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Frais minimums (par exemple frais de stock)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Conditionnement" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Conditionnement de l'article" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Nombre de paquet" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "plusieurs" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Commande multiple" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Quantité disponible auprès du fournisseur" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilité mise à jour" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Date de dernière mise à jour des données de disponibilité" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Rupture de prix pour le fournisseur" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Devise par défaut utilisée pour ce fournisseur" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Nom de l'entreprise" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Ruptures de prix" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Une erreur s'est produite lors de l'exportation des données" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Identifiant de base de données existant pour l'enregistrement" -#: importer/models.py:452 +#: importer/models.py:459 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:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Le champ est déjà associé à une colonne de données" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "La colonne n'existe pas dans le fichier de données" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Le champ n'existe pas dans le modèle cible" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Le champ sélectionné est en lecture seule" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Session d'importation" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Champ d'application" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Colonne" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Index des lignes" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Données de la ligne d'origine" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Erreurs" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Valide" -#: importer/models.py:833 +#: 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:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Aucun enregistrement trouvé avec l'ID fourni" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Format d'ID invalide" @@ -4588,7 +4688,7 @@ msgstr "Nombre de copies à imprimer pour chaque étiquette" msgid "Connected" msgstr "Connecté" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Inconnu" @@ -4692,7 +4792,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:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Groupe" @@ -4720,7 +4820,7 @@ msgstr "Valeur maximale pour le type de progression, requis si type=progress" msgid "Order Reference" msgstr "Référence de commande" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Remarquable" @@ -4728,7 +4828,7 @@ msgstr "Remarquable" msgid "Has Project Code" msgstr "A le code du projet" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Créé par" @@ -4764,57 +4864,69 @@ msgstr "Date cible Avant" msgid "Target Date After" msgstr "Date cible Après" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Possède un Tarif" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Terminé avant" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Terminé après" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Ordre de fabrication externe" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Commande" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Commande Complétée" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Pièces Internes" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Commande En Attente" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Terminé" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Fait l'objet d'une expédition" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Commande d’achat" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Commande d’achat" msgid "Sales Order" msgstr "Commandes" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Prix Total" msgid "Total price for this order" msgstr "Prix total pour cette commande" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Devise de la commande" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Devise de cette commande (laisser vide pour utiliser la devise par défa msgid "This order is locked and cannot be modified" msgstr "Cette commande est verrouillée et ne peut être modifiée" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Le contact ne correspond pas à l'entreprise sélectionnée" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "La date de début doit être antérieure à la date cible" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "L'adresse ne correspond pas à la société sélectionnée" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Description de la commande (facultatif)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Sélectionner le code du projet pour cette commande" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Lien vers une page externe" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Date de début" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Date de début prévue pour cette commande" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Date Cible" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Date d'émission" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Date d'émission de la commande" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Utilisateur ou groupe responsable de cette commande" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Point de contact pour cette commande" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Adresse de l'entreprise pour cette commande" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Référence de la commande" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "État" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Statut de la commande d'achat" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Société de laquelle les articles sont commandés" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Référence du fournisseur" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Code de référence de la commande fournisseur" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "reçu par" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Date à laquelle la commande a été complété" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destination" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Destination des articles reçus" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Le fournisseur de la pièce doit correspondre au fournisseur de la commande" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Le poste ne correspond pas au bon de commande" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Il manque une pièce liée à l'article de la ligne" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "La quantité doit être un nombre positif" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Client" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Société à laquelle les articles sont vendus" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Statut de la commande client" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Référence client " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Code de référence de la commande du client" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Nom de l’expédition" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "expédié par" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "La commande est déjà terminée" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "La commande est déjà annulée" -#: order/models.py:1423 +#: order/models.py:1463 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:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "La commande est verrouillée et ne peut être modifiée" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Nombre d'élement" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Référence du poste" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Notes sur les postes" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Description du poste (facultatif)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contexte supplémentaire pour cette ligne" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Prix unitaire" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Poste du bon de commande" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "La pièce du fournisseur doit correspondre à celle du fournisseur" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "L'ordre de fabrication doit être marqué externe" -#: order/models.py:1904 +#: order/models.py:1971 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:1910 +#: order/models.py:1977 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:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Pièce fournisseur" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Reçu" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Nombre d'éléments reçus" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Prix d'achat" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Prix d'achat unitaire" -#: order/models.py:1978 +#: order/models.py:2056 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:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Ligne supplémentaire du bon de commande" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Poste de commande client" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Prix de vente" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Prix de vente unitaire" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Expédié" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Quantité expédiée" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Envoi de la commande client" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "L'adresse d'expédition doit correspondre au client" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Adresse de livraison pour cet envoi" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Date d'expédition" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Date de Livraison" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Date de livraison de l'envoi" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Vérifié par" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Utilisateur qui a vérifié cet envoi" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envoi" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Numéro d'expédition" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "N° de suivi" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Information de suivi des colis" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "N° de facture" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Numéro de référence de la facture associée" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Le colis a déjà été envoyé" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "L'expédition n'a pas d'articles en stock alloués" -#: order/models.py:2389 +#: order/models.py:2477 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:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Ligne supplémentaire de commande client" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Affectation des commandes clients" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "L'article de stock n'a pas été assigné" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Impossible d'allouer le stock à une ligne sans pièce" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La quantité d'allocation ne peut pas excéder la quantité en stock" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "La quantité allouée doit être supérieure à zéro" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 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:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "La commande client ne correspond pas à l'expédition" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "L'envoi ne correspond pas à la commande client" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Ligne" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Référence de l'expédition de la commande client" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Article" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Sélectionner l'article de stock à affecter" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Saisir la quantité d'allocation de stock" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Retour Référence de la commande" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Entreprise à l'origine du retour des articles" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Statut du retour de commande" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Poste de l'ordre de retour" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "L'article en stock doit être spécifié" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "La quantité retournée dépasse la quantité en stock" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "La quantité retournée doit être supérieure à zéro" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Quantité non valide pour un article de stock sérialisé" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Sélectionner l'article à retourner par le client" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Date de réception" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "La date de réception de cet article en retour" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Résultats" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Résultat pour ce poste" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Ordre de retour Ligne supplémentaire" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID de commande" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID de l'ordre à dupliquer" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Copier des lignes" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Copier les postes de l'ordre original" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Copier les lignes supplémentaires" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Postes de travail" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Lignes achevées" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplicata de commande" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Spécifier les options de duplication de cette commande" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "ID de commande invalide" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Nom du fournisseur" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "La commande ne peut pas être annulée" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "La commande comporte des postes incomplets" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "La commande n'est pas ouverte" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Tarification automobile" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Devise du prix d'achat" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Fusionner des éléments" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Unité de gestion des stocks" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Numéro de pièce interne" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Nom de la pièce interne" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "La pièce du fournisseur doit être spécifiée" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Le bon de commande doit être spécifié" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Le fournisseur doit correspondre au bon de commande" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Le bon de commande doit correspondre au fournisseur" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Poste" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Sélectionner le lieu de destination des envois reçus" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Saisir le code de lot pour les articles de stock entrant" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Date d'expiration" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Saisir la date d'expiration des articles de stock entrant" -#: order/serializers.py:824 +#: order/serializers.py:879 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:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Remplacer les informations d'emballage pour les articles en stock entrants" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Note supplémentaire pour les articles en stock entrant" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Code-barres" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Code-barres scanné" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Le code-barres est déjà utilisé" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Les postes doivent être fournis" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "L'emplacement de la destination doit être spécifié" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Les valeurs de code-barres fournies doivent être uniques" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Envois" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Envois terminés" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "Lignes allouées" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Devise du prix de vente" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Postes alloués" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Aucun détail sur l'expédition n'est fourni" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "La quantité doit être positive" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Entrez les numéros de série à allouer" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "L'envoi a déjà été effectué" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "L'envoi n'est pas associé à cette commande" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Les numéros de série suivants sont indisponibles" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Poste de commande de retour" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Le poste ne correspond pas à l'ordre de retour" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Le poste a déjà été reçu" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Quantité à retourner" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Devise du prix de la ligne" @@ -5598,146 +5742,150 @@ msgstr "Remboursement" msgid "Reject" msgstr "Refuser" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Bon de commande en souffrance" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Le bon de commande {po} est maintenant en retard" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Commande en souffrance" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La commande {so} est maintenant en retard" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Ordre de retour en retard" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "L'ordre de retour {ro} est maintenant en retard" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Étoilé" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filtrer par catégories étoilées" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Profondeur" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtrer par profondeur de catégorie" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Premier niveau" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtrer par catégories de premier niveau" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Cascade" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Inclure les sous-catégories dans les résultats filtrés" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Parent" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filtrer par catégorie de parents" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Exclure les sous-catégories de la catégorie spécifiée" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "A des résultats" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Est variante" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Est la révision" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "A des révisions" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Nomenclature valide" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Catégories en cascade" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 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:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "La pièce d'assemblage est active" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "La pièce d'assemblage est traçable" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "La pièce d'assemblage est testable" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Le composant est testable" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Utilise" @@ -5746,11 +5894,11 @@ msgstr "Utilise" msgid "Part Category" msgstr "Catégorie de composant" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Catégories de composants" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Emplacement par défaut" @@ -5778,7 +5926,7 @@ msgstr "Mots-clés par défaut pour les pièces de cette catégorie" msgid "Icon" msgstr "Icône" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Icône (facultatif)" @@ -5799,1025 +5947,1050 @@ msgstr "Valeur par Défaut" msgid "Default Parameter Value" msgstr "Valeur par défaut du paramètre" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Pièces" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Impossible de supprimer cette partie car elle est verrouillée" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Impossible de supprimer cette partie car elle est toujours active" -#: part/models.py:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "L'IPN doit correspondre au modèle de regex {pattern}" -#: part/models.py:776 +#: part/models.py:777 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:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Impossible d'effectuer une révision d'une partie qui est déjà une révision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Le code de révision doit être spécifié" - -#: part/models.py:797 +#: part/models.py:792 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:804 +#: part/models.py:799 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:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "La partie parentale doit pointer vers le même modèle" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN dupliqué non autorisé dans les paramètres de la pièce" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "La révision de la pièce existe déjà en double." -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 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:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nom de l'article" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Est un modèle" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Cette pièce est-elle une pièce modèle ?" -#: part/models.py:1123 +#: part/models.py:1118 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:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Description de la pièce (facultatif)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Mots-clés" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Catégorie de la pièce" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Numéro de révision ou de version de la pièce" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Révision" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Cette partie est-elle une révision d'une autre partie ?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Révision de" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Où cet article est-il normalement stocké ?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Expiration par défaut" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Stock Minimum" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Niveau de stock minimum autorisé" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Unités de mesure pour cette partie" -#: part/models.py:1254 +#: part/models.py:1258 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:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 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:1272 +#: part/models.py:1276 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:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Cette pièce peut-elle être vendue aux clients ?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Est-ce que cette pièce est active ?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Les parties verrouillées ne peuvent pas être modifiées" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Nomenclature validée" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Est-ce que la nomenclature pour cette pièce est correcte ?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Somme de contrôle de la nomenclature" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Somme de contrôle de la nomenclature enregistrée" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Nomenclature vérifiée par" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Date de vérification de la nomenclature" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Création Utilisateur" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Propriétaire responsable de cette pièce" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Ventes multiples" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Devise utilisée pour cacher les calculs de prix" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Coût minimum de la nomenclature" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Coût minimal des composants" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Coût maximal de la nomenclature" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Coût maximal des composants" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Coût d'achat minimum" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Coût d'achat historique minimum" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Coût d'achat maximum" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Coût d'achat historique maximum" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Prix interne minimum" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Coût minimum basé sur des ruptures de prix internes" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Prix interne maximum" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Coût maximum basé sur les écarts de prix internes" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Prix minimum du fournisseur" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Prix minimum des pièces provenant de fournisseurs externes" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Prix maximum du fournisseur" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Prix maximum des pièces provenant de fournisseurs externes" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Coût minimum de la variante" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Calcul du coût minimum des pièces de la variante" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Coût maximal de la variante" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Calcul du coût maximal des pièces de la variante" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Coût minimal" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Remplacer le coût minimum" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Coût maximal" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Dépassement du coût maximal" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Calcul du coût minimum global" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Calcul du coût maximum global" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Prix de vente minimum" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Prix de vente minimum basé sur des ruptures de prix" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Prix de vente maximum" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Prix de vente maximum en fonction des écarts de prix" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Coût minimum de vente" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Prix de vente historique minimum" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Coût de vente maximum" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Prix de vente historique maximum" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Partie pour l'inventaire" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Nombre d'articles" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Nombre d'entrées individuelles au moment de l'inventaire" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Stock total disponible au moment de l'inventaire" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Date" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Date de l'inventaire" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Coût minimum du stock" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Coût minimum estimé des stocks disponibles" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Coût maximal du stock" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Coût maximum estimé des stocks disponibles" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Vente de pièces détachées Prix cassé" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Modèle de test partiel" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nom de test" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Entrez un nom pour le test" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Clé de test" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Clé simplifiée pour le test" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Description du test" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Saisir la description de ce test" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Ce test est-il activé ?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Requis" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Ce test est-il obligatoire pour passer l'examen ?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Valeur requise" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Nécessite une pièce jointe" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Choix valables pour ce test (séparés par des virgules)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 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:3961 +#: part/models.py:4030 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:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Sélectionner la partie parentale" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sous-partie" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Sélectionner la pièce à utiliser dans la nomenclature" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Quantité de nomenclature pour ce poste de nomenclature" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Ce poste de nomenclature est facultatif" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Définir la quantité" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Attrition" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Arrondi au multiple" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Référence du poste de nomenclature" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notes sur les postes de nomenclature" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Somme de contrôle" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Somme de contrôle de la ligne de nomenclature" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validée" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Ce poste de nomenclature a été validé" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Obtient l'héritage" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 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:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "La sous-partie doit être spécifiée" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Remplacement d'un poste de nomenclature" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Poste de nomenclature parent" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Pièce de rechange" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Première partie" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Partie 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Sélectionner une partie connexe" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Note pour cette relation" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Une relation en double existe déjà" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Catégorie de parents" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Catégorie de pièce mère" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Sous-catégories" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Résultats" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Nombre de résultats enregistrés par rapport à ce modèle" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Devise d'achat de l'item" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Le fichier n'est pas une image" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Partie originale" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Sélectionner la partie originale à dupliquer" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Copier l'image" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Copier l'image à partir de la partie originale" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copier la nomenclature" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Copier les paramètres" - -#: part/serializers.py:404 +#: 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:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Notes sur la copie" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Copier les notes de la partie originale" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Test Copie" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Quantité de stock initial" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Emplacement initial du stock" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Spécifier l'emplacement du stock initial pour cette pièce" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Sélectionner le fournisseur (ou laisser en blanc pour passer)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Sélectionner le fabricant (ou laisser en blanc pour ignorer)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Numéro de pièce du fabricant" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "L'entreprise sélectionnée n'est pas un fournisseur valide" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "L'entreprise sélectionnée n'est pas un fabricant valide" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "La pièce du fabricant correspondant à ce MPN existe déjà" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "La pièce du fournisseur correspondant à cette UGS existe déjà" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Nom catégorie" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Construction" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Quantité de cette pièce actuellement en production" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Quantité exceptionnelle de cette pièce sont planifié à la fabrication" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Éléments en stock" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Révisions" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Stock total" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Stock non attribué" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Variante Stock" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Dupliquer une pièce" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Copier les données initiales d'une autre partie" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Stock initial" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Créer une pièce avec une quantité de stock initiale" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Informations sur le fournisseur" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Ajouter les informations initiales du fournisseur pour cette pièce" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Copier les paramètres de la catégorie" -#: part/serializers.py:948 +#: part/serializers.py:994 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:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Image existante" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Nom de fichier d'une image de pièce existante" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Le fichier image n'existe pas" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Valider l'ensemble de la nomenclature" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Peut construire" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Nécessaire pour fabrication" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Alloué à la fabrication" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Nécessaire pour les commandes" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Alloué aux commandes" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Prix Minimum" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Remplacer la valeur calculée pour le prix minimum" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Prix minimum monnaie" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Prix Maximum" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Remplacer la valeur calculée pour le prix maximum" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Devise du prix maximum" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Mise à jour" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Mise à jour des prix pour cette pièce" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Sélectionner l'assemblage parent" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Sélectionner le composant" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Sélectionner la pièce à partir de laquelle copier la nomenclature" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Supprimer les données existantes" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Supprimer les postes de nomenclature existants avant de les copier" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Inclure l'héritage" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Sauter les lignes non valides" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Activez cette option pour ignorer les lignes non valides" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Copier les pièces de remplacement" -#: part/serializers.py:1924 +#: part/serializers.py:2016 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:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notification de stock faible" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Pas de date d'expieatio" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Expire aujourd’hui" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} jours" @@ -7031,15 +7204,15 @@ msgstr "Quantité à allouer" msgid "Label printing failed" msgstr "Échec de l'impression de l'étiquette" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Erreur de rendu de l'étiquette au format PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Erreur de rendu de l'étiquette en HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Aucun élément fourni pour l'impression" @@ -7100,7 +7273,7 @@ msgstr "Prise en charge native des codes-barres" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Notification de changement de pièce" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "La partie `{part.name}` a été déclenchée par un événement `{part_action}`" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Imprimante d'étiquettes PDF InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Mode débogage" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activer le mode débogage - renvoie du HTML brut au lieu du PDF" @@ -7500,7 +7673,7 @@ msgstr "Frontière" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Paysage" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Seuls les membres du personnel peuvent administrer les plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "L'installation du plugin est désactivée" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Installation réussie du plugin" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Installation du plugin dans {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Le plugin n'a pas été trouvé dans le registre" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Le plugin n'est pas un plugin packagé" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Le nom du paquet du plugin n'a pas été trouvé" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Seuls les membres du personnel peuvent administrer les plugins" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "La désinstallation des plugins est désactivée" -#: plugin/installer.py:341 +#: plugin/installer.py:351 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:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Le plugin n'est pas installé" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "L'installation du plugin n'a pas été trouvée" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Désinstallation réussie du plugin" @@ -7689,21 +7875,21 @@ msgstr "Plugin Package" msgid "Plugin" msgstr "Extension" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Aucun auteur trouvé" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Le plugin nécessite au moins la version {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Le plugin nécessite au maximum la version {v}" @@ -7884,55 +8070,55 @@ msgstr "Installation non confirmée" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Recharge complète" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Effectuer un rechargement complet du registre des plugins" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Forcer le rechargement" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Forcer le rechargement du registre des plugins, même s'il est déjà chargé" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Collecter les plugins" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Collecter les plugins et les ajouter au registre" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Activer le plugin" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Activer ce plugin" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Supprimer la configuration" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Supprimer la configuration du plugin de la base de données" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Articles" @@ -7948,7 +8134,7 @@ msgstr "Le plugin ne prend pas en charge l'impression d'étiquettes" msgid "Invalid label dimensions" msgstr "Dimensions de l'étiquette non valides" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Aucun élément valide n'a été fourni au modèle" @@ -7972,152 +8158,156 @@ msgstr "Lettre" msgid "Template file with this name already exists" msgstr "Le fichier modèle portant ce nom existe déjà" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nom du modèle" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Description du modèle" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Numéro de révision (auto-incrémentation)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Joindre au modèle sur l'impression" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Modèle de nom de fichier" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Modèle de génération de noms de fichiers" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Le modèle est activé" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Type de modèle cible pour le modèle" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtres" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Fichier modèle" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Taille des pages pour les rapports PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Rendre le rapport en orientation paysage" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Fusionner" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Rapport généré à partir du modèle {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Erreur dans la génération du rapport" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Largeur [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Largeur de l'étiquette, spécifiée en mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Hauteur [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Hauteur de l'étiquette, spécifiée en mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Erreur d'impression des étiquettes" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Extrait " -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Fichier d'extrait de rapport" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Description du fichier d'extrait" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Elément" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Rapport sur le fichier d'actifs" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Description du fichier d'actifs" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Sélectionner un modèle de rapport" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 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:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Sélection du modèle d'étiquette" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Plugin d'impression" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Sélectionner le plugin à utiliser pour l'impression des étiquettes" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numéro de série" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Éléments installés" @@ -8248,184 +8438,196 @@ msgstr "Pas de résultat (obligatoire)" msgid "No result" msgstr "Pas de résultat" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Le fichier d'actifs n'existe pas" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Fichier image non trouvé" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "la balise part_image nécessite une instance de Part" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "la balise company_image nécessite une instance d'entreprise" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filtrer par profondeur de localisation" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Filtrer par lieux de premier niveau" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Inclure les sous-emplacements dans les résultats filtrés" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Emplacement parent" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtrer par emplacement parent" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Nom de la pièce (insensible à la casse)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Le nom de la pièce contient (insensible à la casse)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Nom de la pièce (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Partie IPN (insensible à la casse)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "La partie IPN contient (insensible à la casse)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Partie IPN (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Stock minimum" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Stock maximum" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Code de statut" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Emplacement externe" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Consommé par l'ordre de construction" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Installé dans un autre article en stock" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Arbre en pièces détachées" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Mise à jour avant" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Mise à jour après" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Inventaire avant" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Inventaire après" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Date d'expiration avant" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Date d’expiration après" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Périmé" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "La quantité est requise" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "La partie valide doit être fournie" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Le fournisseur donné n'existe pas" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Types d'emplacements de stock" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Emplacement du stock" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Emplacement des stocks" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Propriétaire" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Sélectionner un propriétaire" @@ -8461,7 +8663,7 @@ msgstr "Sélectionner un propriétaire" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Externe" @@ -8481,274 +8683,282 @@ msgstr "Type d'emplacement du stock de cet emplacement" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "La pièce doit être spécifiée" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 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:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "L'objet ne peut pas s'appartenir à lui-même" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Poste de stock parent" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Pièce de base" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Où se trouve cet article en stock ?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "L'emballage de cet article en stock est stocké dans" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Installé dans" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "L'article a été installé dans un autre article ?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Numéro de série pour cet article" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Code de lot pour cet article de stock" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Quantité en stock" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Source Construire" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Construire pour cet article en stock" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Consommé par" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Ordre de construction qui a consommé cet article de stock" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Bon de commande source" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Commande d'achat pour cet article en stock" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Destination de la commande client" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Supprimer lors de l'épuisement" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Supprimer ce poste de stock lorsque le stock est épuisé" -#: stock/models.py:1207 +#: stock/models.py:1233 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:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Converti en partie" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 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:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "La quantité doit être un nombre entier" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 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:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "La quantité ne correspond pas au nombre de numéros de série" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Le modèle de test n'existe pas" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Un article de stock a été affecté à une commande client" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "L'article de stock est installé dans un autre article" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "L'article de stock contient d'autres articles" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Un article de stock a été affecté à un client" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "L'article de stock est actuellement en production" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Le stock sérialisé ne peut pas être fusionné" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Articles de stock en double" -#: stock/models.py:2096 +#: stock/models.py:2122 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:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Les codes d'état des stocks doivent correspondre" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Suivi des articles en stock" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Notes d'entrée" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Résultat du test de l'article en stock" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Une valeur doit être fournie pour ce test" -#: stock/models.py:3028 +#: stock/models.py:3054 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:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Valeur non valide pour ce test" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Résultat du test" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Valeur de sortie du test" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Pièce jointe au résultat du test" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Notes de test" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Station de test" -#: stock/models.py:3085 +#: stock/models.py:3111 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:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Commencé" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Horodatage du début du test" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Fini" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Horodatage de la fin du test" @@ -8792,246 +9002,246 @@ msgstr "Sélectionner la pièce pour laquelle un numéro de série doit être g msgid "Quantity of serial numbers to generate" msgstr "Nombre de numéros de série à générer" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Modèle de test pour ce résultat" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 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:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Article Parent" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Article de stock parent" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Entrez les numéros de série pour les nouveaux articles" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Référence du fournisseur" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Expiré" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Éléments enfants" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Suivi des éléments" -#: stock/serializers.py:643 +#: stock/serializers.py:668 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:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Entrez le nombre d'articles en stock à sérialiser" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Emplacement du stock de destination" -#: stock/serializers.py:735 +#: stock/serializers.py:760 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:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Les numéros de série existent déjà" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Sélectionner l'article de stock à installer" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Quantité à installer" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Saisir la quantité d'articles à installer" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Ajouter une note de transaction (facultatif)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "La quantité à installer doit être d'au moins 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "L'article en stock n'est pas disponible" -#: stock/serializers.py:845 +#: stock/serializers.py:870 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:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "La quantité à installer ne doit pas dépasser la quantité disponible" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Emplacement de destination de l'élément désinstallé" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Code d'état de l'article en stock" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Sélectionner les articles en stock pour modifier leur statut" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Aucun article en stock n'a été sélectionné" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sous-localisations" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Emplacement du stock mère" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "La pièce doit être vendable" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "L'article est affecté à une commande client" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "L'article est attribué à un ordre de fabrication" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Affectation d'articles en stock par le client" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "L'entreprise sélectionnée n'est pas un client" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Notes d'affectation des stocks" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Une liste des articles en stock doit être fournie" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notes sur les fusions d'actions" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Autoriser les fournisseurs non concordants" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Autoriser la non-concordance des statuts" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Au moins deux articles en stock doivent être fournis" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Pas de changement" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Valeur de la clé primaire StockItem" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "L'article n'est plus en stock" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Notes sur les transactions boursières" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Numéro de série suivant" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Numéro de série précédent" @@ -9369,227 +9579,247 @@ msgstr "Dernière utilisation du jeton" msgid "Revoked" msgstr "Révoquée" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Droit défini" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Vue" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Droit de voir des éléments" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Ajouter" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Droit d'ajouter des éléments" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Modifier" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Droit de modifier des élément" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Supprimer" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Droit de supprimer des éléments" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Bot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Interne" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Invité" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Langue" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Langue préférée de l'utilisateur" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Thème" -#: users/models.py:514 +#: users/models.py:512 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:519 +#: users/models.py:517 msgid "Widgets" msgstr "Raccourcis" -#: users/models.py:521 +#: users/models.py:519 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:528 +#: users/models.py:526 msgid "Display Name" msgstr "Nom d'affichage" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Nom d'affichage choisi pour l'utilisateur" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Localisation" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Intitulé de l'emploi principal ou du poste" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Message sur le statut de l'utilisateur" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Informations sur la localisation de l'utilisateur" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "L'utilisateur utilise activement le système" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Coordonnées préférées de l'utilisateur" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Type d'utilisateur" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "De quel type d'utilisateur s'agit-il ?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organisation" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Organisation/affiliation principale de l'utilisateur" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Groupe primaire" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Groupe principal de l'utilisateur" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administrateur" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Bons de commande" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Ventes" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Commandes de retour" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nom d'utilisateur" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Prénom" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Prénom de l'utilisateur" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Nom" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Nom de famille de l'utilisateur" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Adresse e-mail de l'utilisateur" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Cet utilisateur a-t-il les permissions du staff" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Super-utilisateur" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Cet utilisateur est-il un super-utilisateur" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Ce compte d'utilisateur est-il actif" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Seul un superutilisateur peut modifier ce champ" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Mot de passe" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Mot de passe pour l'utilisateur" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Écraser l'alerte sur les règles de mot de passe" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Vous n'avez pas le droit de créer des utilisateurs" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Votre compte a été créé." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 baff9344dc..00965ce03b 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "למשתמש אין הרשאה לצפות במוזל הזה" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "" @@ -112,13 +105,13 @@ msgstr "הזן תאריך סיום" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "מספרים סידוריים לא נמצאו" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "אימייל" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "הפניה חייבת להתאים לדפוס הנדרש" msgid "Reference number is too large" msgstr "מספר האסמכתה גדול מדי" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "בחירה שגויה" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "שם" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "תיאור" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "תיאור (לא חובה)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "נתיב" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "שמות כפולים אינם יכולים להתקיים תחת אותו אב" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "הערות סימון (אופציונלי)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "נתוני ברקוד" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "נתוני ברקוד של צד שלישי" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "ברקוד Hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash ייחודי של נתוני ברקוד" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "נמצא ברקוד קיים" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "שגיאת שרת" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "נרשמה שגיאה על ידי השרת." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "המספר חייב להיות תקין" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "מטבע" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "בחר מטבע מהאפשרויות הזמינות" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "סינית (פשוטה)" msgid "Chinese (Traditional)" msgstr "סינית (מסורתית)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "קוד מטבע לא מאושר" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "מקור הבנייה" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "רכיב" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "מקט" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "בחר רכיב לבנייה" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "כמות בניה" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "קישור חיצוני" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "כמות" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "מספרים סידוריים" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "מבוטל" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "הושלם" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "משתמש" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "קישור" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "קובץ מצורף" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "קובץ חסר" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "חסר קישור חיצוני" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "בחר קובץ לצירוף" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "הערה" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "שם קובץ" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "נשלח" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "שם משתמש" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "שם פרטי" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 0abbe4120d..d218890f60 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Hindi\n" "Language: hi_IN\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "" @@ -112,13 +105,13 @@ msgstr "तारीख दर्ज करें" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "कनेक्शन त्रुटि" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "ई-मेल" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 7ce08360d5..9eadd76556 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Hungarian\n" "Language: hu_HU\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API funkciót nem találom" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Tömeges művelethez tételek vagy szűrők megadása kötelező" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "A tételeket listában kell átadni" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Érvénytelen a tétel lista" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "A szűrőket dict - szótár - formában kell megadni" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Érvénytelen szűrők vannak megadva" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Minden szűrő csak true értékkel használható" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Nincs a szűrésnek megfelelő tétel" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nincs adat megadva" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Ennek a mezőnek egyedinek kell lennie." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Nincs jogosultságod az adatok megtekintéséhez" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Nem megfelelő mennyiség" @@ -112,13 +105,13 @@ msgstr "Dátum megadása" msgid "Invalid decimal value" msgstr "Érvénytelen decimális érték" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Megjegyzések" @@ -131,75 +124,91 @@ msgstr "A(z) '{name}' érték nem a szükséges minta szerinti" 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:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Nem lehet 1000 tételnél többet szerializálni" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Üres sorozatszám" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplikált sorozatszám" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Érvénytelen csoport: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nem található sorozatszám" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "HTML tag-ek eltávolítása ebből az értékből" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Az adatban tiltott markdown tartalom található" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Csatlakozási hiba" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "A kiszolgáló érvénytelen státuszkóddal válaszolt" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Kivétel történt" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "A kiszolgáló érvénytelen Content-Length értéket adott" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "A kép mérete túl nagy" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "A kép letöltés meghaladja a maximális méretet" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "A kiszolgáló üres választ adott" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "A megadott URL nem egy érvényes kép fájl" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Az azonosítónak egyeznie kell a mintával" msgid "Reference number is too large" msgstr "Azonosító szám túl nagy" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Érvénytelen választás" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Név" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Leírás" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Leírás (opcionális)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Elérési út" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikált nevek nem lehetnek ugyanazon szülő alatt" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown megjegyzések (opcionális)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Vonalkód adat" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Harmadik féltől származó vonalkód adat" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Vonalkód hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Egyedi vonalkód hash" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Létező vonalkód" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Feladat hiba" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Az '{f}' háttérfeladat elbukott {n} próbálkozás után" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Kiszolgálóhiba" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "A kiszolgáló egy hibaüzenetet rögzített." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Érvényes számnak kell lennie" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Pénznem" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Válassz pénznemet a lehetőségek közül" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Ez a mező nem lehet null." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Érvénytelen érték" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Távoli kép" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "A távoli kép URL-je" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Képek letöltése távoli URL-ről nem engedélyezett" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Nem sikerült letölteni a képet a távoli URL-ről" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Érvénytelen tartalomtípus-formátum" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Tartalomtípus nem található" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "A tartalomtípus nem egyezik a szükséges mixin osztállyal" @@ -537,11 +521,11 @@ msgstr "Kínai (egyszerűsített)" msgid "Chinese (Traditional)" msgstr "Kínai (Hagyományos)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Frissítés elérhető" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "InvenTree frissítés elérhető" @@ -553,30 +537,30 @@ msgstr "Érvénytelen fizikai mértékegység" msgid "Not a valid currency code" msgstr "Érvénytelen pénznem kód" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Rendelés állapota" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Szülő gyártás" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Változatokkal együtt" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Változatokkal együtt" msgid "Part" msgstr "Alkatrész" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategória" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Szülő Gyártás" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Hozzám rendelt" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Hozzárendelve" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Ez előtt létrehozva" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Létrehozva ez után" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Van kezdeti dátuma" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Kezdeti dátum ez előtt" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Kezdeti dátum ez után" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Van céldátum" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Céldátum ez előtt" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Céldátum ez után" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Elkészült ez előtt" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Elkészült ez után" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Ettől a dátumtól" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Eddig a dátumig" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Fa kihagyása" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Fogyóeszköz" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcionális" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Gyártmány" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Követett" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Ellenőrizhető" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Befejezetlen rendelés" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Lefoglalva" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Felhasználva" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Rendelve" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "Gyártás nem található" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 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:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Hely" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Kimenet" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Gyártási utasítások" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Az alkatrészjegyzék még nincs jóváhagyva" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Meg kell adni felelős felhasználót vagy csoportot" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Gyártási rendelés alkatrész nem változtatható" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Céldátumnak a kezdeti dátum után kell lennie" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Gyártási utasítás azonosító" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Gyártási utasítás azonosító" msgid "Reference" msgstr "Azonosító" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Gyártás rövid leírása (opcionális)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "Gyártási megrendelés, amelyhez ez a gyártás hozzá van rendelve" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Válassz alkatrészt a gyártáshoz" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Vevői rendelés azonosító" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "Vevői rendelés, amelyhez ez a gyártás tartozik" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Forrás hely" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Külső gyártás" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Ez a gyártási rendelés külsőleg teljesül" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Cél hely" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Gyártási mennyiség" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Gyártandó készlet tételek száma" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Kész tételek" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Elkészült készlet tételek száma" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Gyártási állapot" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Gyártás státusz kód" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Batch kód" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Batch kód a gyártás kimenetéhez" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Létrehozás dátuma" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Gyártás kezdeti dátuma" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Gyártási rendelés ütemezett kezdeti dátuma" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Befejezés cél dátuma" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Befejezés dátuma" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "elkészítette" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Indította" -#: build/models.py:399 +#: build/models.py:402 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:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Felelős" -#: build/models.py:409 +#: build/models.py:420 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:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Külső link" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link külső URL-re" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Priorítás" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Gyártási utasítás priorítása" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Projektszám" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Projekt kód a gyártáshoz" -#: build/models.py:686 +#: build/models.py:697 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:691 +#: build/models.py:702 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:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Gyártási utasítás elkészült" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nincs gyártási kimenet megadva" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Gyártási kimenet már kész" -#: build/models.py:1019 +#: build/models.py:1030 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:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Mennyiségnek nullánál többnek kell lennie" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 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:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "A lefoglalt készletelemek még gyártás alatt vannak" -#: build/models.py:1208 +#: build/models.py:1221 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:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Gyártási Rendelés Sor Tétel" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Gyártás objektum" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,450 +1017,446 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Mennyiség" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Gyártáshoz szükséges mennyiség" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Felhasznált készlet mennyisége" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "A készlet tétel nem egyezik az alkatrészjegyzékkel" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "A lefoglalt mennyiségnek nullánál nagyobbnak kell lennie" -#: build/models.py:1972 +#: build/models.py:1986 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:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Készlet túlfoglalva" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Készlet tétel" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Forrás készlet tétel" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Készlet mennyiség amit foglaljunk a gyártáshoz" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Beépítés ebbe" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Cél készlet tétel" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Gyártási Szint" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Alkatrész neve" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Gyártás kimenet" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Ez a gyártási kimenet már elkészült" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Ez a gyártási kimenet nincs teljesen lefoglalva" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Add meg a mennyiséget a gyártás kimenetéhez" -#: build/serializers.py:333 +#: build/serializers.py:339 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:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Sorozatszámok" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Add meg a sorozatszámokat a gyártás kimenetéhez" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Legyártott készlet helye" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Sorozatszámok automatikus hozzárendelése" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "A gyártási kimenetek listáját meg kell adni" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Selejtezet gyártási kimenetek helye" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Foglalások törlése" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Selejtezett kimenetek foglalásainak felszabadítása" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Selejtezés oka" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "A kész gyártási kimenetek helye" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Hiányos foglalás elfogadása" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Lefoglalt készlet felhasználása" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Befejezetlen kimenetek törlése" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "A nem befejezett gyártási kimenetek törlése" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Nem engedélyezett" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Gyártásban fel lett használva" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Foglalás felszabadítása a készre jelentés előtt" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Túlfoglalt készlet" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Pár készlet tétel túl lett foglalva" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Kiosztatlanok elfogadása" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "A szükséges készlet nem lett teljesen lefoglalva" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Befejezetlenek elfogadása" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Szükséges gyártási mennyiség nem lett elérve" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "A Gyártásnak nyitott leszármazott Gyártása van" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "A Gyártásnak folyamatban kell lennie" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "A gyártási utasítás befejezetlen kimeneteket tartalmaz" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Gyártás sor" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Gyártás kimenet" -#: build/serializers.py:879 +#: build/serializers.py:885 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:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Gyártás sor tétel" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "A tételnek kell legyen készlete" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "A lefoglalandó tételeket meg kell adni" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Hely kizárása" -#: build/serializers.py:1099 +#: build/serializers.py:1105 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:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Felcserélhető készlet" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Készlet helyettesítés" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Helyettesítő alkatrészek foglalásának engedélyezése" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Opcionális tételek" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Opcionális tételek lefoglalása a gyártáshoz" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "Összes elem" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "Nem követett tételek" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "Követett tételek" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "Tétel típusa" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Válasszon tétel típust az automatikus foglaláshoz" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Nem sikerült az automatikus lefoglalás feladatot elindítani" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Alkatrészjegyzék Hivatkozás" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "Alkatrészjegyzék Cikk Azonosító" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Alkatrészjegyzék Alkatrész Név" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "Beépítés helye" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Gyártás" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Beszállítói alkatrész" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Lefoglalt mennyiség" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Gyártási Hivatkozás" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Alkatrész kategória Neve" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Követésre kötelezett" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Örökölt" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Változatok" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Alkatrészjegyzék tétel" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Gyártásban" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Gyártás Ütemezve" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Külső raktárkészlet" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Elérhető készlet" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Elérhető Helyettesítő Készlet" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Elérhető Készlet Változatokból" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Felhasznált mennyiség meghaladja a lefoglalt mennyiséget" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Megjegyzés a készletfelhasználáshoz" -#: build/serializers.py:1806 +#: build/serializers.py:1807 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:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Dupla gyártási tétel lefoglalás" -#: build/serializers.py:1829 +#: build/serializers.py:1830 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:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Duplikált gyártási sor foglalás" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Legalább egy tétel vagy sor megadása kötelező" @@ -1496,43 +1480,47 @@ msgstr "Felfüggesztve" msgid "Cancelled" msgstr "Törölve" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Kész" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "A gyártási utasításhoz készlet szükséges" -#: build/tasks.py:241 +#: build/tasks.py:228 #, 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:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Késésben lévő gyártás" -#: build/tasks.py:270 +#: build/tasks.py:257 #, 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:711 +#: common/api.py:722 msgid "Is Link" msgstr "Ez egy hivatkozás" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Ez egy állomány" -#: common/api.py:766 +#: common/api.py:777 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:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "A felhasználó nem jogosult ezen melléklet törlésére" @@ -1552,798 +1540,822 @@ msgstr "Hiányzó érvényes valuta kód" msgid "No plugin" msgstr "Nincsen plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Projekt kód címke" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Frissítve" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Legutóbbi frissítés időpontja" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Frissítette" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Az objektumot utoljára módosította" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Egyedi projektszám" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projekt leírása" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Beállítási kulcs" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Beállítás értéke" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Az érték bináris kell legyen" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Az érték egész szám kell legyen" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Az értéknek számnak kell lennie" -#: common/models.py:893 +#: 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:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Kulcs string egyedi kell legyen" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Felhasználó" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Ársáv mennyiség" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Ár" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Egységár egy meghatározott mennyiség esetén" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Végpont" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Végpont ahol ez a webhook érkezik" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Webhook neve" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktív" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Aktív-e ez a webhook" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token a hozzáféréshez" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Titok" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Megosztott titok a HMAC-hoz" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Üzenet azonosító" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Egyedi azonosító ehhez az üzenethez" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Kiszolgáló" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Kiszolgáló ahonnan ez az üzenet érkezett" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Fejléc" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Üzenet fejléce" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Törzs" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Üzenet törzse" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Végpont amin ez az üzenet érkezett" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Dolgozott rajta" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Befejeződött a munka ezzel az üzenettel?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Azonosító" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Cím" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Közzétéve" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Szerző" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Összefoglaló" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Elolvasva" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Elolvasva?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Képfájl" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "A képhez tartozó model típus" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "A képhez tartozó model azonosító" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Egyedi mértékegység" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "A mértékegység szimbólumának egyedinek kell lennie" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "A mértékegységnek valós azonosítónak kell lennie" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Egység neve" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Szimbólum" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Opcionális mértékegység szimbólum" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definíció" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Mértékegység definíció" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Melléklet" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Hiányzó fájl" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Hiányzó külső link" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Modell típusa" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Képhez tartozó model típus" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Válaszd ki a mellekelni kívánt fájlt" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Megjegyzés" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Melléklet megjegyzés" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Feltöltés dátuma" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "A fájl feltöltésének dátuma" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Fájl mérete" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Fájlméret bájtban" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "A melléklet model típusa érvénytelen" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Egyedi Állapot" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Egyedi Állapotok" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Hivatkozott Állapot Készlet" -#: common/models.py:2102 +#: common/models.py:2184 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:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logikai kulcs" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Érték" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "A model adatbázisba tárolandó szám" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Az állapot neve" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Címke" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "A felületen megjelenített címke" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Szín" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "A felöleten megjelenő szín" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "A Model amihez ez az állapot tartozik" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Modelt választani kötelező" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Kulcsot választani kötelező" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Logikai kulcsot választani kötelező" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "A kulcs és a logikai kulcs nem lehet azonos" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Helyes hivatkozási állapot osztályt kell megadni" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Választéklista" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Választéklisták" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Választéklista neve" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Választéklista leírása" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Lezárt" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Választéklista lezárva?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Választéklista használható?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Forrás plugin" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Választéklista szolgáltató plugin" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Forrás szöveg" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Elhagyható lista forrás azonosító szöveg" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Alapértelmezett bejegyzés" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Alapértelmezett elem ezen a listán" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Létrehozva" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Választéklista létrehozási dátuma és ideje" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Utoljára módosítva" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Választéklista bejegyzés" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Választéklista bejegyzések" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Választéklista amihez ez a bejegyzés tartozik" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Választéklista bejegyzés értéke" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Választéklista bejegyzés felirata" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Választéklista bejegyzés leírása" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Választéklista bejegyzés aktív?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Paraméter sablon" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Paraméter Sablonok" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Jelölőnégyzet paraméternek nem lehet mértékegysége" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Jelölőnégyzet paraméternek nem lehetnek választási lehetőségei" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "A lehetőségek egyediek kell legyenek" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "A paraméter sablon nevének egyedinek kell lennie" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Célmodell típusa ehhez a paramétersablonhoz" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Paraméter neve" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Mértékegység" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Paraméter mértékegysége" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Paraméter leírása" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Jelölőnégyzet" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Ez a paraméter egy jelölőnégyzet?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Lehetőségek" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Választható lehetőségek (vesszővel elválasztva)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "A paraméter választéklistája" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Engedélyezve" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Ez a paramétersablon engedélyezett?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Paraméter" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Paraméterek" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Hibás választás a paraméterre" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Érvénytelen modelltípus megadva a paraméterhez" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "Modell ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "A célmodell azonosítója ehhez a paraméterhez" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Sablon" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Paraméter sablon" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Adat" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Paraméter értéke" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Megjegyzés" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Opcionális megjegyzés mező" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Vonalkód beolvasás" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Vonalkód adat" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Melyik felhasználó olvasta be a vonalkódot" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Időbélyeg" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Vonalkód beolvasás dátuma és ideje" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Vonalkód feldolgozó URL végpont" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontextus" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Vonalkód olvasás kontextus adat" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Válasz" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Vonalkód olvasó válasz adat" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Eredmény" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Vonalkód olvasás sikeres volt?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Hiba történt" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "E-mail üzenet" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "E-mail üzenetek" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Bejelentve" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Elküldve" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Megbukott" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Kiszállítva" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Megerősítve" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Bejövő" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Kimenő" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Nincs válasz" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Kiszállítás követése" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Olvasási visszaigazolás" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Kattintások nyomkövetése" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Globális ID" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "Szál ID" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Szál" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Ehhez az üzenethez kapcsolódó üzenet-lánc" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Prioritás" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Email szál" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Email szálak" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Kulcs" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Üzenetlánc egyedi azonosítója" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Belső kezdés" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Ez az üzenetlánc belül indult?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Az üzenetlánc kezdeti dátuma és ideje" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Az üzenetlánc utolsó módosításának dátuma és ideje" @@ -2365,7 +2377,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Készlet érkezett" @@ -2379,11 +2391,11 @@ msgstr "Készlet érkezett vissza egy visszavétel miatt" #: common/serializers.py:125 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "Jelzi, hogy a beállítás módosítása megerősítést igényel-e" #: common/serializers.py:139 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" +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 msgid "Indicates if the setting is overridden by an environment variable" @@ -2393,1235 +2405,1303 @@ msgstr "Ez a beállítás felül van bírálva egy környezeti változó által" msgid "Override" msgstr "Felülbírálás" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Folyamatban" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Folyamatban lévő feladatok" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Ütemezett Feladatok" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Hibás feladatok" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Feladat ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Egyedi feladat ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Zárol" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Zárolási idő" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Feladat neve" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funkció" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funkció neve" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Paraméterek" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Feladat paraméterei" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Kulcsszó paraméterek" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Feladat kulcsszó paraméterek" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Fájlnév" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Modell típusa" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Választéklista lezárva" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Nincs csoport" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "A site URL blokkolva van a konfigurációban" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Újraindítás szükséges" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Egy olyan beállítás megváltozott ami a kiszolgáló újraindítását igényli" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Függőben levő migrációk" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Függőben levő adatbázis migrációk" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Aktív figyelmeztető kódok" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Aktív figyelmeztető kódok dict-je" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "Példány azonosító" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Az InvenTree példány egyedi azonosítója" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Bejelentési ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Azonosítsa-e magát az szerver a példányazonosítóval a szerver állapotban (authentikáció nélkül)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Kiszolgáló példány neve" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "String leíró a kiszolgáló példányhoz" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Példány név használata" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Példány név használata a címsorban" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Verzió infók megjelenítésének tiltása" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Verzió infók megjelenítése csak admin felhasználóknak" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Cég neve" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Belső cégnév" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Kiindulási URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Kiindulási URL a kiszolgáló példányhoz" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Alapértelmezett pénznem" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Válassz alap pénznemet az ár számításokhoz" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Támogatott valuták" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Támogatott valuták listája" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Árfolyam frissítési gyakoriság" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "nap" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Árfolyam frissítő plugin" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Kiválasztott árfolyam frissítő plugin" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Letöltés URL-ről" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Képek és fájlok letöltésének engedélyezése külső URL-ről" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Letöltési méret korlát" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maximum megengedett letöltési mérete a távoli képeknek" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Felhasznált User-agent az URL-ről letöltéshez" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "A külső URL-ről letöltéshez használt user-agent felülbírálásának engedélyezése (hagyd üresen az alapértelmezéshez)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Erős URL validáció" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Sablon specifikáció igénylése az URL validálásnál" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Frissítés keresés gyakorisága" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Milyen gyakran ellenőrizze van-e új frissítés (0=soha)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatikus biztonsági mentés" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Adatbázis és média fájlok automatikus biztonsági mentése" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automata biztonsági mentés gyakorisága" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Hány naponta készüljön automatikus biztonsági mentés" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Feladat törlési gyakoriság" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Háttérfolyamat eredmények törlése megadott nap eltelte után" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Hibanapló törlési gyakoriság" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Hibanapló bejegyzések törlése megadott nap eltelte után" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Értesítés törlési gyakoriság" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Felhasználói értesítések törlése megadott nap eltelte után" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Email törlési gyakoriság" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Email üzenetek törlése megadott nap eltelte után" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Email napló védett" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Megakadályozza az email napló bejegyzések törlését" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Vonalkód támogatás" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Vonalkód olvasó támogatás engedélyezése a web felületen" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Vonalkód olvasás eredmények tárolása" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Vonalkód olvasási eredmények tárolása az adatbázisban" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maximálisan tárolt vonalkód olvasások mennyisége" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Maximálisan tárolt vonalkód olvasások száma" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Vonalkód beadási késleltetés" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Vonalkód beadáskor a feldolgozás késleltetési ideje" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Webkamerás vonalkód olvasás" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Webkamerás kódolvasás engedélyezése a böngészőből" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Vonalkód Adat Megjelenítése" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Vonalkód adat megjelenítése a böngészőben szövegként" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Vonalkód Generáló Plugin" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Belső vonalkód generálásra használatos plugin" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Alkatrész változatok" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Alkatrész változat vagy verziószám tulajdonság használata" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Csak Összeállítás Verzió" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Csak összeállított alkatrészeknek lehessen verziója" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Lehessen törölni az Összeállításból" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN reguláris kifejezés" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Reguláris kifejezés ami illeszkedik az alkatrész IPN-re" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Többször is előforduló IPN engedélyezése" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Azonos IPN használható legyen több alkatrészre is" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "IPN szerkesztésének engedélyezése" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Alkatrészjegyzék adatok másolása" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Alkatrész paraméterek másolása" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Alkatrész teszt adatok másolása" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kategória paraméter sablonok másolása" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Alkatrészek alapból sablon alkatrészek legyenek" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Összetevő" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Beszerezhető" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Alkatrészek alapból beszerezhetők legyenek" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Értékesíthető" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Alkatrészek alapból eladhatók legyenek" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Alkatrészek alapból követésre kötelezettek legyenek" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuális" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Alkatrészek alapból virtuálisak legyenek" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Kapcsolódó alkatrészek megjelenítése" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Alkatrész kapcsolódó alkatrészeinek megjelenítése" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Kezdeti készlet adatok" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Kezdeti beszállítói adatok" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Alkatrész név megjelenítés formátuma" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formátum az alkatrész név megjelenítéséhez" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Alkatrész kategória alapértelmezett ikon" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Alkatrész kategória alapértelmezett ikon (üres ha nincs)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Áraknál használt tizedesjegyek min. száma" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Áraknál használt tizedesjegyek max. száma" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Beszállítói árazás használata" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Beszerzési előzmények felülbírálása" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Készlet tétel ár használata" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Készlet tétel ár kora" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Alkatrészváltozat árak használata" -#: common/setting/system.py:599 +#: common/setting/system.py:592 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:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Csak az aktív változatokat" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Árazás automatikus frissítése" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Árazás újraszámítás gyakoriság" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "Árak automatikus frissítése ennyi nap után" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Belső árak" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Alkatrészekhez belső ár engedélyezése" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Belső ár felülbírálása" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "Nulla mennyiség engedélyezése az anyagjegyzékben" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Címke nyomtatás engedélyezése" -#: common/setting/system.py:642 +#: common/setting/system.py:643 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:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Címke kép DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Riportok engedélyezése" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Riportok előállításának engedélyezése" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Debug mód" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Riportok előállítása HTML formátumban (hibakereséshez)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Jelentési hibák naplózása" -#: common/setting/system.py:668 +#: common/setting/system.py:669 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:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Lapméret" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Alapértelmezett lapméret a PDF riportokhoz" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Csak választható mértékegységek" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globálisan egyedi sorozatszámok" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Kimerült készlet törlése" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Batch kód sablon" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Készlet lejárata" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Készlet lejárat kezelésének engedélyezése" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Lejárt készlet értékesítése" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Lejárt készlet értékesítésének engedélyezése" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Álló készlet ideje" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Lejárt készlet gyártása" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Gyártás engedélyezése lejárt készletből" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Készlet tulajdonosok kezelése" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Hely alapértelmezett ikon" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Hely alapértelmezett ikon (üres ha nincs)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Beépített készlet megjelenítése" -#: common/setting/system.py:744 +#: common/setting/system.py:757 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:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Tételek telepítésekor a darabjegyzék ellenőrzése" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Lehet Hiányzó Készletet Mozgatni" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Gyártási utasítás azonosító minta" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Felelős tulajdonos szükséges" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Minden rendeléshez felelőst kell rendelni" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Szükséges Aktív Alkatrész" -#: common/setting/system.py:778 +#: common/setting/system.py:791 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:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Elvárás a Lezárt Alkatrész" -#: common/setting/system.py:784 +#: common/setting/system.py:797 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:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Jóváhagyott Alkatrészjegyzék Kötelező" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Leszármazott Gyártásoknak Lezártnak Kell Lennie" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Külső Gyártási Rendelések" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Engedélyezze a külső gyártási rendelés funkciót" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blokkolás a tesztek sikeres végrehajtásáig" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Visszavétel engedélyezése" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Visszavételek engedélyezése a felületen" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Visszavétel azonosító minta" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Befejezett visszavétel szerkesztése" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Vevői rendelés azonosító minta" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Vevői rendeléshez alapértelmezett szállítmány" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Befejezett vevői rendelés szerkesztése" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Szállítmány Ellenőrzést Igényel" -#: common/setting/system.py:873 +#: common/setting/system.py:894 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:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Leszállított Rendelések Készre jelölése" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Beszerzési rendelés azonosító minta" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Befejezett beszerzési rendelés szerkesztése" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Jelenlegi pénznem" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Beszerzési rendelések automatikus befejezése" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Elfelejtett jelszó engedélyezése" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Elfelejtett jelszó funkció engedélyezése a bejentkező oldalon" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Regisztráció engedélyezése" -#: common/setting/system.py:931 +#: common/setting/system.py:960 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSO engedélyezése" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "SSO engedélyezése a bejelentkező oldalon" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "SSO regisztráció engedélyezése" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "SSO csoport szinkronizálás engedélyezése" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO csoport kulcs" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSO csoport hozzárendelés" -#: common/setting/system.py:966 +#: 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 "Az SSO csoportok hozzárendelése az InvenTree csoportokhoz. Ha a helyi csoport nem létezik, létre lesz hozva." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Az SSO-n kívüli csoportok eltávolítása" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email szükséges" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Kötelező email megadás regisztrációkor" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "SSO felhasználók automatikus kitöltése" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Email kétszer" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Jelszó kétszer" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Engedélyezett domainek" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Csoport regisztráláskor" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Többfaktoros hitelesítés kényszerítése" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "A felhasználóknak többfaktoros hitelesítést kell használniuk." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Pluginok ellenőrzése indításkor" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Plugin frissítések ellenőrzése" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "URL integráció engedélyezése" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 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:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Navigációs integráció engedélyezése" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 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:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "App integráció engedélyezése" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "App hozzáadásának engedélyezése a pluginok számára" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Ütemezés integráció engedélyezése" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 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:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Esemény integráció engedélyezése" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 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:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Interfész integráció engedélyezése" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 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:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Email integráció engedélyezése" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 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:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Projektszámok engedélyezése" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Projectek nyomkövetéséhez projekt kódok engedélyezése" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Külső helyek nélkül" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Automatikus leltár időpontja" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "Készlettörténet törlési gyakoriság" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Felhasználók teljes nevének megjelenítése" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Felhasználói profilok megjelenítése" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Felhasználói profilok megjelenítése a profil oldalukon" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Teszt állomás adatok engedélyezése" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Gép Ping Engedélyezése" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 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" @@ -3906,21 +3986,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Hibariportok fogadása" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Értesítések fogadása a rendszerhibákról" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Utoljára használt nyomtató gépek" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Minden modell" @@ -3966,365 +4062,369 @@ msgstr "Az alkatrész aktív" msgid "Manufacturer is Active" msgstr "A Gyártó Aktív" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "A Szállítói Alkatrész Aktív" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "A saját alkatrész Aktív" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "A Beszállító Aktív" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Gyártó" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Cég" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Van készleten" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Cégek" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Cég leírása" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "A cég leírása" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Weboldal" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Cég weboldala" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefonszám" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kapcsolattartó telefonszáma" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kapcsolattartó email címe" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Névjegy" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Kapcsolattartó" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link a külső céginformációhoz" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Ez a vállalat aktív?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Vevő" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Értékesítesz alkatrészeket ennek a cégnek?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Beszállító" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Vásárolsz alkatrészeket ettől a cégtől?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Gyártó" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Gyárt ez a cég alkatrészeket?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Cég által használt alapértelmezett pénznem" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "Adószám" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "Céges adószám" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Cím" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Címek" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Cég kiválasztása" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Cím megnevezése" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Címhez tartozó leírás, megnevezés" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Elsődleges cím" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Beállítás elsődleges címként" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "1. sor" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Cím első sora" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "2. sor" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Cím második sora" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Irányítószám" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Város/Régió" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Irányítószám város/régió" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Állam/Megye" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Állam vagy megye" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Ország" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Cím országa" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Megjegyzés a futárnak" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Futárnak szóló megjegyzések" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Belső szállítási megjegyzések" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Szállítási megjegyzések belső használatra" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link a címinformációkhoz (külső)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Gyártói alkatrész" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Kiindulási alkatrész" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Válassz alkatrészt" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Gyártó kiválasztása" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN (Gyártói cikkszám)" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Gyártói cikkszám" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL link a gyártói alkatrészhez" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Gyártói alkatrész leírása" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Csomagolási mennyiségnek nullánál többnek kell lennie" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Beszállító" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Beszállító kiválasztása" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Beszállítói cikkszám" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Ez a szállítói termék aktív?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "Elsődleges" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Gyártói alkatrész kiválasztása" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL link a beszállítói alkatrészhez" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Beszállítói alkatrész leírása" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "alap költség" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimális díj (pl. tárolási díj)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Csomagolás" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Alkatrész csomagolás" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Csomagolási mennyiség" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "többszörös" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Többszörös rendelés" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Beszállítónál elérhető mennyiség" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Elérhetőség frissítve" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Utolsó elérhetőségi adat frissítés" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Beszállítói Ár Kedvezmény" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Beszállító által használt alapértelmezett pénznem" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Cégnév" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Készleten" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Árkategóriák" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Hiba történt adatexportálás közben" @@ -4429,67 +4529,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Létező adatbázis azonosító a rekordhoz" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Oszlop már adatbázis mezőhöz lett rendelve" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Adatbázis mező már adatfájl oszlophoz lett rendelve" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Az Oszlop nem létezik ebben a fájlban" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "A mező nem létezik a cél adatszerkezetben" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Kijelölt mező csak olvasható" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Importálási művelet" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Mező" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Oszlop" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Sor száma" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Eredeti sor adat" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Hibák" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Érvényes" -#: importer/models.py:833 +#: 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:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Nem található rekord a megadott ID-vel" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Érvénytelen az ID formátuma" @@ -4589,7 +4689,7 @@ msgstr "Címkénkénti nyomtatandó mennyiség" msgid "Connected" msgstr "Csatlakoztatba" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Ismeretlen" @@ -4693,7 +4793,7 @@ msgstr "A tulajdonság kulcsa" msgid "Value of the property" msgstr "A tulajdonság értéke" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Csoport" @@ -4721,7 +4821,7 @@ msgstr "Maximális érték az előrehaladás típushoz, kötelező ha típus=el msgid "Order Reference" msgstr "Rendelés azonosítója" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Kintlévő" @@ -4729,7 +4829,7 @@ msgstr "Kintlévő" msgid "Has Project Code" msgstr "Van projektszáma" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Készítette" @@ -4765,57 +4865,69 @@ msgstr "Céldátum ez előtt" msgid "Target Date After" msgstr "Céldátum ez után" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Van árazás" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Ez előtt befejezve" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Befejezve ez után" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Külső Gyártási Rendelés" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Rendelés" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "A rendelés teljesítve" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Belső alkatrész" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "A rendelés függőben" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Kész" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Van kiszállítás" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Beszerzési rendelés" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4823,8 +4935,8 @@ msgstr "Beszerzési rendelés" msgid "Sales Order" msgstr "Vevői rendelés" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4840,11 +4952,11 @@ msgstr "Teljes ár" msgid "Total price for this order" msgstr "A rendelés teljes ára" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Rendelés pénzneme" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4852,718 +4964,750 @@ msgstr "Megrendeléshez használt pénznem (hagyd üresen a cégnél alapértelm 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:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "A kapcsolattartó nem egyezik a kiválasztott céggel" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "A kezdeti dátumnak meg kell előznie a céldátumot" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "A cím nem egyezik a kiválasztott vállalattal" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Rendelés leírása (opcionális)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Válassz projektszámot ehhez a rendeléshez" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link külső weboldalra" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Kezdés dátuma" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "A tervezett kezdeti dátum ehhez a gyártáshoz" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Cél dátum" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Kiállítás dátuma" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Kiállítás dátuma" #: order/models.py:506 +msgid "Updated At" +msgstr "Frissítve" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Felhasználó vagy csoport aki felelőse ennek a rendelésnek" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Kapcsolattartó ehhez a rendeléshez" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Cég címei ehhez a rendeléshez" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Rendelés azonosító" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Állapot" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Beszerzési rendelés állapota" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Cég akitől a tételek beszerzésre kerülnek" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Beszállítói azonosító" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Beszállítói rendelés azonosító kód" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "érkeztette" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Rendelés teljesítési dátuma" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Cél" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Beérkezett tételek tárolója" -#: order/models.py:727 +#: order/models.py:751 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:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Sortétel nem egyezik a beszerzési megrendeléssel" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Sortételen hiányzik a kapcsolódó alkatrész" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Mennyiség pozitív kell legyen" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Vevő" -#: order/models.py:1327 +#: order/models.py:1367 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:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Értékesítési rendelés állapot" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Vevői azonosító " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Megrendelés azonosító kódja a vevőnél" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Kiszállítás dátuma" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "szállította" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Rendelés már teljesítve" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Rendelés már visszavonva" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Csak nyitott rendelés jelölhető késznek" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 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:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Tétel mennyiség" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Sortétel azonosító" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Sortétel megjegyzései" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Sortétel leírása (opcionális)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "További kontextus ehhez a sorhoz" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Egységár" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Vevői Rendelés Sortétel" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Beszállítói alkatrésznek egyeznie kell a beszállítóval" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Gyártási rendelést külsőnek kell jelölni" -#: order/models.py:1904 +#: order/models.py:1971 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:1910 +#: order/models.py:1977 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:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Beszállítói alkatrész" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Beérkezett" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Érkezett tételek száma" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Beszerzési ár" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Beszerzési egységár" -#: order/models.py:1978 +#: order/models.py:2056 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:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Vevői Rendelés Extra Sor" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Vevői Rendelés Sortétel" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Eladási ár" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Eladási egységár" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Kiszállítva" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Szállított mennyiség" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Vevői Rendelés Szállítása" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "A szállítási címnek egyeznie kell az ügyféllel" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Szállítási cím ehhez a szállítmányhoz" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Szállítás dátuma" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Szállítási dátum" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Kézbesítés dátuma" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Ellenőrizte" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Felhasználó aki ellenőrizte ezt a szállítmányt" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Szállítmány" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Szállítmány száma" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Nyomkövetési szám" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Szállítmány nyomkövetési információ" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Számlaszám" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Hozzátartozó számla referencia száma" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Szállítmány már elküldve" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Szállítmány nem tartalmaz foglalt készlet tételeket" -#: order/models.py:2389 +#: order/models.py:2477 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:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Vevői Rendelés Extra Sor" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Vevői rendeléshez foglalások" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Készlet tétel nincs hozzárendelve" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "A lefoglalandó mennyiség nem haladhatja meg a készlet mennyiségét" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Lefoglalt mennyiségnek nullánál többnek kell lennie" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 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:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Vevői rendelés nem egyezik a szállítmánnyal" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Szállítmány nem egyezik a vevői rendeléssel" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Sor" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Vevői rendelés szállítmány azonosító" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Tétel" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Válaszd ki a foglalásra szánt készlet tételt" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Készlet foglalási mennyiség megadása" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Visszavétel azonosító" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Cég akitől a tételek visszavételre kerülnek" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Visszavétel állapota" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Visszavétel sortétel" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Készlettételt meg kell adni" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Visszavétel mennyisége meghaladja a készletet" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Visszavétel mennyisége nullánál nagyobb kell, hogy legyen" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Érvénytelen mennyiség szerializált készlettételnél" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Válaszd ki a vevőtől visszavenni kívánt tételt" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Visszavétel dátuma" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Kimenetel" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Sortétel végső kimenetele" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Visszavétel extra tétel" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Rendelés azonosító" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "A duplikálandó megrendelés száma" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Sorok másolása" -#: order/serializers.py:88 +#: 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:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Extra sorok másolása" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Sortételek" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Kész sorok" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Rendelés duplikálása" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Rendelés másolás beállításai" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Érvénytelen rendelés ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Beszállító neve" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "A rendelést nem lehet törölni" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "A rendelésben teljesítetlen sortételek vannak" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "A rendelés nem nyitott" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automata árazás" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Beszérzési ár pénzneme" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Elemek összevonása" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU (leltári azonosító)" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Belső cikkszám" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Belső cikkszám" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Beszállítói alkatrészt meg kell adni" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Beszerzési rendelést meg kell adni" -#: order/serializers.py:734 +#: order/serializers.py:785 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:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "A beszerzési rendelésnek egyeznie kell a beszállítóval" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Sortétel" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Válassz cél helyet a beérkezett tételeknek" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Írd be a batch kódját a beérkezett tételeknek" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Lejárati dátum" -#: order/serializers.py:816 +#: order/serializers.py:871 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:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Írd be a sorozatszámokat a beérkezett tételekhez" -#: order/serializers.py:834 +#: order/serializers.py:889 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:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Kiegészítő megjegyzés beérkező készlettételekhez" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Vonalkód" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Beolvasott vonalkód" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Ez a vonalkód már használva van" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Sortételt meg kell adni" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "A cél helyet kötelező megadni" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Megadott vonalkódoknak egyedieknek kel lenniük" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Szállítások" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Kész szállítmányok" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Eladási ár pénzneme" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Foglalt tételek" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nincsenek szállítmány részletek megadva" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Mennyiség pozitív kell legyen" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Írd be a sorozatszámokat a kiosztáshoz" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Szállítmány kiszállítva" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Szállítmány nincs hozzárendelve ehhez a rendeléshez" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Az alábbi sorozatszámok nem elérhetők" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Visszavétel sortétel" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Sortétel nem egyezik a visszavétellel" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "A sortétel már beérkezett" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Visszaküldési mennyiség" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Sortétel pénzneme" @@ -5599,146 +5743,150 @@ msgstr "Visszatérítés" msgid "Reject" msgstr "Elutasított" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Késésben lévő beszerzés" -#: order/tasks.py:52 +#: order/tasks.py:53 #, 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:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Késésben lévő vevői rendelés" -#: order/tasks.py:122 +#: order/tasks.py:123 #, 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:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Lejárt visszvételi utasítás" -#: order/tasks.py:189 +#: order/tasks.py:190 #, 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:103 +#: part/api.py:88 msgid "Starred" msgstr "Csillagozott" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Csillagozottra szűrés" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Mélység" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Kategória mélységre szűrés" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Felső szint" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Csúcs készlethelyre szűrés" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Lépcsőzetes" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Szűrt eredmények tartalmazzák az alkategóriákat" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Szülő" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Szülő kategóriára szűrés" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Az adott kategória alkategóriáinak kihagyása" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Van találat" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Változat-e" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Változat" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Vannak Változatok" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Alkatrészjegyzék ellenőrizve" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Kaszkád Kategóriák" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 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:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Összeállított Alkatrész ellenőrizhető" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Összetevő alkatrész ellenőrizhető" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Használ" @@ -5747,11 +5895,11 @@ msgstr "Használ" msgid "Part Category" msgstr "Alkatrész kategória" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Alkatrész kategóriák" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Alapértelmezett hely" @@ -5779,7 +5927,7 @@ msgstr "Ebben a kategóriában évő alkatrészek kulcsszavai alapban" msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikon (opcionális)" @@ -5800,1025 +5948,1050 @@ msgstr "Alapértelmezett érték" msgid "Default Parameter Value" msgstr "Alapértelmezett paraméter érték" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Alkatrészek" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Nem lehet törölni egy zárolt alkatrész paramétereit" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Nem lehet módosítani egy zárolt alkatrész paramétereit" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Lezárt alkatrész nem törölhető" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Aktív alkatrész nem törölhető" -#: part/models.py:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, 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:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Alkatrész nem lehes saját magának verziója" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Nem lehet olyan alkatrészből új verziót csinálni ami már eleve egy verzió" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Verzió kódot meg kell adni" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Verziók csak összeállított alkatrészeknél engedélyezettek" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Nem lehet sablon alkatrészből új verziót csinálni" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "A szülő alkatrésznek azonos sablonra kell mutatnia" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 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:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Adott alkatrész verzióból már létezik egy." -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Szerkezeti kategóriákhoz nem lehet alkatrészeket rendelni!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Alkatrész neve" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Sablon-e" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Ez egy sablon alkatrész?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Ez az alkatrész egy másik változata?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Ebből a sablonból" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Alkatrész leírása (opcionális)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Kulcsszavak" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Alkatrész kategória" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN (Belső Cikkszám)" -#: part/models.py:1164 +#: part/models.py:1159 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:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Változat" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Ez egy másik alkatrész egy verziója?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Ennek a verziója" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Alapban hol tároljuk ezt az alkatrészt?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Alapértelmezett lejárat" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimális készlet" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimálisan megengedett készlet mennyiség" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Alkatrész mértékegysége" -#: part/models.py:1254 +#: part/models.py:1258 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:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 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:1272 +#: part/models.py:1276 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:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 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:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Aktív-e ez az alkatrész?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Lezárt alkatrészt nem lehet szerkeszteni" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Alkatrészjegyzék ellenőrizve" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Az alkatrész anyagjegyzéke érvényes?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Alkatrészjegyzék ellenőrző összeg" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Tárolt alkatrészjegyzék ellenőrző összeg" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Alkatrészjegyzéket ellenőrizte" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Alkatrészjegyzék ellenőrzési dátuma" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Létrehozó" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Alkatrész felelőse" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Több értékesítése" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Árszámítások gyorstárazásához használt pénznem" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimum alkatrészjegyzék költség" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Összetevők minimum költsége" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maximum alkatrészjegyzék költség" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Összetevők maximum költsége" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimum beszerzési ár" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Eddigi minimum beszerzési költség" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maximum beszerzési ár" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Eddigi maximum beszerzési költség" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimum belső ár" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimum költség a belső ársávok alapján" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maximum belső ár" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maximum költség a belső ársávok alapján" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimum beszállítói ár" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Minimum alkatrész ár a beszállítóktól" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maximum beszállítói ár" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maximum alkatrész ár a beszállítóktól" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimum alkatrészváltozat ár" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Alkatrészváltozatok számolt minimum költsége" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maximum alkatrészváltozat ár" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Alkatrészváltozatok számolt maximum költsége" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimum költség" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Minimum költség felülbírálása" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maximum költség" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Maximum költség felülbírálása" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Számított általános minimum költség" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Számított általános maximum költség" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimum eladási ár" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Minimum eladási ár az ársávok alapján" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maximum eladási ár" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maximum eladási ár az ársávok alapján" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimum eladási költség" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Eddigi minimum eladási ár" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maximum eladási költség" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Eddigi maximum eladási ár" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Leltározható alkatrész" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Tételszám" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Egyedi készlet tételek száma a leltárkor" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Teljes készlet a leltárkor" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Dátum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Leltározva ekkor" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimum készlet érték" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Becsült minimum raktárkészlet érték" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maximum készlet érték" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Becsült maximum raktárkészlet érték" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Alkatrész értékesítési ársáv" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Alkatrész Teszt Sablon" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Teszt név" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Add meg a teszt nevét" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Teszt azonosító" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Egyszerűsített Teszt azonosító" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Teszt leírása" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Adj hozzá egy leírást ehhez a teszthez" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Teszt engedélyezve?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Kötelező" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Szükséges-e hogy ez a teszt sikeres legyen?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Kötelező érték" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Kötelező melléklet" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Választható lehetőségek ehhez a Teszthez (vesszővel elválasztva)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 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:3961 +#: part/models.py:4030 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:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Szülő alkatrész kiválasztása" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Al alkatrész" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Válaszd ki az alkatrészjegyzékben használandó alkatrészt" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Alkatrészjegyzék mennyiség ehhez az alkatrészjegyzék tételhez" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Ez az alkatrészjegyzék tétel opcionális" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Beállítás mennyiség" -#: part/models.py:4014 +#: part/models.py:4091 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:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Veszteség" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Kerekítési többszörös" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Alkatrészjegyzék tétel azonosító" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Alkatrészjegyzék tétel megjegyzései" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Ellenőrző összeg" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Alkatrészjegyzék sor ellenőrző összeg" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Jóváhagyva" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Ez a BOM tétel jóvá lett hagyva" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Öröklődött" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 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:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Al alkatrészt kötelező megadni" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Alkatrészjegyzék tétel helyettesítő" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Szülő alkatrészjegyzék tétel" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Helyettesítő alkatrész" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "1.rész" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "2.rész" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Válassz kapcsolódó alkatrészt" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Kapcsolati megjegyzés" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "Alkatrész kapcsolat nem hozható létre önmagával" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Már létezik duplikált alkatrész kapcsolat" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Szülő Kategória" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Felsőbb szintű alkatrész kategória" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Alkategóriák" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Eredmények" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Eszerint a sablon szerint rögzített eredmények száma" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Beszerzési pénzneme ennek a készlet tételnek" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "A fájl nem kép" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Eredeti alkatrész" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Válassz eredeti alkatrészt a másoláshoz" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kép másolása" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Kép másolása az eredeti alkatrészről" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Alkatrészjegyzék másolása" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Paraméterek másolása" - -#: part/serializers.py:404 +#: 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:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Megjegyzések másolása" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Megjegyzések másolása az eredeti alkatrészről" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Teszt másolása" -#: part/serializers.py:418 +#: 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:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Kezdeti készlet mennyiség" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Kezdeti készlet hely" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Add meg a kezdeti készlet helyét" -#: part/serializers.py:463 +#: part/serializers.py:474 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:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Válassz gyártót (hagyd üresen ha nem kell létrehozni)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Gyártói cikkszám" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "A kiválasztott cég nem érvényes beszállító" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "A kiválasztott cég nem érvényes gyártó" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Van már ilyen gyártói alkatrész" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Van már ilyen beszállítói alkatrész" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategória neve" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Gyártásban" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Az alkatrészből jelenleg ennyi van gyártás alatt" -#: part/serializers.py:823 +#: part/serializers.py:850 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:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Készlet tételek" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Verziók" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Teljes készlet" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Nem lefoglalt készlet" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Variánsok Raktárkészlet" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Alkatrész másolása" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kezdeti adatok másolása egy másik alkatrészről" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Kezdeti készlet" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Kezdeti készlet mennyiség létrehozása" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Beszállító információ" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Kezdeti beszállító adatok hozzáadása" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kategória paraméterek másolása" -#: part/serializers.py:948 +#: part/serializers.py:994 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:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Meglévő kép" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "A meglévő alkatrész képfájl neve" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "A képfájl nem létezik" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Teljes alkatrészjegyzék jóváhagyása" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Gyártható" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Gyártásokhoz szükséges" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Gyártási rendelésekhez foglalva" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Értékesítési rendeléshez szükséges" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Értékesítési rendeléshez lefoglalva" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimum ár" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Számított minimum ár felülbírálása" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Minimum ár pénzneme" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maximum ár" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Számított maximum ár felülbírálása" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Maximum ár pénzneme" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Frissítés" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Alkatrész árak frissítése" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "A Minimum ár nem lehet nagyobb mint a Maximum ár" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "A Maximum ár nem lehet kisebb mint a Minimum ár" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Szülő összeállítás kiválasztása" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Összetevő alkatrész kijelölése" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Válassz alkatrészt ahonnan az alkatrészjegyzéket másoljuk" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Létező adat törlése" -#: part/serializers.py:1906 +#: part/serializers.py:1998 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:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Örököltekkel együtt" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Hibás sorok kihagyása" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Engedély a hibás sorok kihagyására" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Helyettesítő alkatrészek másolása" -#: part/serializers.py:1924 +#: part/serializers.py:2016 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:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Alacsony készlet értesítés" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Álló készlet értesítés" -#: part/tasks.py:77 +#: part/tasks.py:78 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:79 +#: part/tasks.py:80 #, 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:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Nincs lejárati dátuma" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} napja lejárt" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Ma jár le" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} nap" @@ -7032,15 +7205,15 @@ msgstr "Lefoglalandó mennyiség" msgid "Label printing failed" msgstr "Címkenyomtatás sikertelen" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "A címke PDF nyomtatása sikertelen" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "A címke HTML nyomtatása sikertelen" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Nincs elem a nyomtatáshoz" @@ -7101,7 +7274,7 @@ msgstr "Alapvető vonalkód támogatást ad" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7447,20 +7620,20 @@ msgstr "Változott alkatrész értesítés" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "A `{part.name}` alkatrészt aktiválták egy `{part_action}` eseménnyel" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF címkenyomtató" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Debug mód" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Debug mód engedélyezése - nyers HTML-t ad vissza PDF helyett" @@ -7501,7 +7674,7 @@ msgstr "Szegély" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Fekvő" @@ -7581,64 +7754,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Csak a személyzeti felhasználók adminisztrálhatják a pluginokat" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Plugin telepítés letiltva" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin telepítése sikeres" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin telepítve ide: {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Ez a plugin nem található a tárolóban" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "A plugin nem egy csomagolt plugin" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Plugin csomag neve nem található" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Csak a személyzeti felhasználók adminisztrálhatják a pluginokat" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Plugin eltávolítás letiltva" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin nem eltávolítható mivel még aktív" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Kötelező plugint nem lehet uninstallálni" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Plugin nem uninstallálható mert mintaplugin" -#: plugin/installer.py:357 +#: plugin/installer.py:367 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:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Plugin nincs telepítve" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Plugin telepítés nem található" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Plugin eltávolítása sikeres" @@ -7690,21 +7876,21 @@ msgstr "Csomag plugin" msgid "Plugin" msgstr "Bővítmény" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nincs szerző" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "A pluginhoz minimum {v} verzió kell" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "A pluginhoz maximum {v} verzió kell" @@ -7885,55 +8071,55 @@ msgstr "Tlepítés nincs megerősítve" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Teljes újratöltés" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "A plugin tárolók teljes újratöltése" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Kényszerített újratöltés" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Akkor is töltse újra a plugin tárolót ha már be lett töltve" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Pluginok begyűjtése" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Pluginok begyűjtése és a tárolóhoz adása" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Plugin aktiválása" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Plugin bekapcsolása" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Kötelező plugint nem lehet kikapcsolni" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Konfiguráció törlése" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Plugin konfiguráció törlése az adatbázisból" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 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:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Tételek" @@ -7949,7 +8135,7 @@ msgstr "Plugin nem támogatja a címkenyomtatást" msgid "Invalid label dimensions" msgstr "Érvénytelen címke méretek" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Nincs érvényes tétel megadva a sablonhoz" @@ -7973,152 +8159,156 @@ msgstr "„Letter” méret" msgid "Template file with this name already exists" msgstr "Ilyen nevű Sablon fájl már létezik" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Sablon neve" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Sablon leírása" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Verziószám (automatikusan nő)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "A nyomtatáson a modelhez kapcsolás" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Fájlnév minta" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Minta a fájlnevek előállításához" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Sablon engedélyezve" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "A sablon által célzott model típus" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Szűrők" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Sablon file" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Lapméret a PDF riportokhoz" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Jelentés fekvő nézetben" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Összevonás" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Jelentés renderelése a kiválasztott tételekhez" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Jelentés a {self.name} sablon alapján" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Szintaxis hiba a sablonban" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Hiba a jelentés renderelésekor" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Hiba a jelentés generálása során" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Hiba a jelentés kimenetének összefésülése során" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Szélesség [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Címke szélessége, mm-ben" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Magasság [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Címke magassága, mm-ben" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Címkenyomtatási hiba" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Részlet" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Riport részlet fájl" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Részlet fájl leírása" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Eszköz" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Riport asset fájl" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Asset fájl leírása" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Riport sablon kiválasztása" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "A jelentésben levő tételek azonosítója" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Címke sablon választás" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Nyomtató plugin" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Címkenyomtató plugin kiválasztása" @@ -8191,7 +8381,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sorozatszám" @@ -8216,7 +8406,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Beépített tételek" @@ -8249,184 +8439,196 @@ msgstr "Nincs eredmény (szükséges)" msgid "No result" msgstr "Nincs eredmény" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "A fájl nem létezik" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "A képfile nem található" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 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:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image elem csak cég példánynál használható" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Hely mélységre szűrés" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Csúcs készlethelyre szűrés" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Szűrt eredmények tartalmazzák az alhelyeket" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Szülő hely" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Szülő helyre szűrés" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Alkatrész neve (kisbetű/nagybetű nem számít)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Az alkatrész neve tartalmazza (kisbetű/nagybetű nem számít)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Alkatrész neve (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Alkatrész IPN (kisbetű/nagybetű nem számít)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Alkatrész IPN tartalmazza (kisbetű/nagybetű nem számít)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Alkatrész IPN (regexp)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Minimális készlet" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Maximális készlet" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Státuszkód" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Külső hely" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Felhasználva Gyártási Rendelésben" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Más készlettételbe beépítve" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Alkatrész fa" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Módosítva ezelőtt" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Frissítve ez után" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Leltárazva ezelőtt" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Leltárazva ezután" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Lejárat előtt" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Lejárat után" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Állott" -#: stock/api.py:963 +#: 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:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "Készlethelyek alábontása" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "Az al-készlethelyeket is beleértve" -#: stock/api.py:988 +#: stock/api.py:987 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:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Mennyiség megadása kötelező" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Egy érvényes alkatrészt meg kell adni" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "A megadott beszállítói alkatrész nem létezik" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "Beépítettek Belefoglalása" -#: stock/api.py:1403 +#: stock/api.py:1411 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:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "Szűrés numerikus készlettétel azonosító szerint" -#: stock/api.py:1431 +#: stock/api.py:1439 #, 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:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8442,19 +8644,19 @@ msgstr "Készlethely típusok" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Készlet hely" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Készlethelyek" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Tulajdonos" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Tulajdonos kiválasztása" @@ -8462,7 +8664,7 @@ msgstr "Tulajdonos kiválasztása" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Külső" @@ -8482,274 +8684,282 @@ msgstr "Tárolóhely típus" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "a(z) {field} nem létezik" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Alkatrész kiválasztása kötelező" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "A szerkezeti raktári helyre nem lehet készletet felvenni!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Virtuális alkatrészből nem lehet készletet létrehozni" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "A tétel nem tartozhat saját magához" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Szülő készlet tétel" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Kiindulási alkatrész" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Hol található ez az alkatrész?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 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:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Beépítve ebbe" -#: stock/models.py:1073 +#: stock/models.py:1099 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:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Sorozatszám ehhez a tételhez" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Batch kód ehhez a készlet tételhez" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Készlet mennyiség" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Forrás gyártás" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Gyártás ehhez a készlet tételhez" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Felhasználva ebben" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Felhasználva ebben a gyártásban" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Forrás beszerzési rendelés" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Beszerzés ehhez a készlet tételhez" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Cél vevői rendelés" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Törlés ha kimerül" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Készlet tétel törlése ha kimerül" -#: stock/models.py:1207 +#: stock/models.py:1233 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:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Alkatrésszé alakítva" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "Mennyiség meghaladja az elérhető készletet" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Az alkatrész nem követésre kötelezett" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Mennyiség egész szám kell legyen" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Sorozatszámokat listában kell megadni" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "A mennyiség nem egyezik a megadott sorozatszámok számával" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "Nem lehet készletet strukturális helyre rendelni" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Ez a Teszt sablon nem létezik" -#: stock/models.py:2069 +#: stock/models.py:2095 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:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Készlet tétel beépül egy másikba" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "A készlet tétel más tételeket tartalmaz" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Készlet tétel hozzárendelve egy vevőhöz" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Készlet tétel gyártás alatt" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Követésre kötelezett készlet nem vonható össze" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Duplikált készlet tételek vannak" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "A készlet tétel ugyanarra az alkatrészre kell vonatkozzon" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Készlet tételek állapotainak egyeznie kell" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Készlettörténet" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Bejegyzés megjegyzései" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Készlet Tétel Ellenőrzés Eredménye" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Ehhez a teszthez meg kell adni értéket" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Ehhez a teszthez fel kell tölteni mellékletet" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "A teszt eredménye érvénytelen" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Teszt eredménye" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Teszt kimeneti értéke" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Teszt eredmény melléklet" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Tesztek megjegyzései" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Teszt állomás" -#: stock/models.py:3085 +#: stock/models.py:3111 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:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Elkezdődött" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "A teszt indításának időpontja" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Befejezve" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "A teszt befejezésének időpontja" @@ -8793,246 +9003,246 @@ msgstr "Válassza ki az alkatrészt amihez sorozatszámot akar generálni" msgid "Quantity of serial numbers to generate" msgstr "Hány sorozatszámot generáljunk" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Az eredmény Teszt sablonja" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "Ehhez az alkatrészhez nem tartozik ellenőrzés" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "Sablon azonosító vagy Teszt név szükséges" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Szülő tétel" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Szülő készlet tétel" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "Csomagméret használata" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Írd be a sorozatszámokat az új tételekhez" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Beszállítói Cikkszám" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Lejárt" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Gyermek tételek" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Nyilvántartott tételek" -#: stock/serializers.py:643 +#: stock/serializers.py:668 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:681 +#: stock/serializers.py:706 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:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "Nincsen készlettétel megadva" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Cél készlet hely" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Sorozatszámokat nem lehet hozzárendelni ehhez az alkatrészhez" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "A sorozatszámok már léteznek" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Válaszd ki a beépítésre szánt készlet tételt" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Beépítendő mennyiség" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Adja meg a beépítendő mennyiséget" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Tranzakció megjegyzés hozzáadása (opcionális)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "A beépítendő mennyiség legalább 1 legyen" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Készlet tétel nem elérhető" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "A kiválasztott alkatrész nincs az alkatrészjegyzékben" -#: stock/serializers.py:858 +#: stock/serializers.py:883 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:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Cél hely a kiszedett tételeknek" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Készlet tétel státusz kódja" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 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:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Nincs készlet tétel kiválasztva" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Alhelyek" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Felsőbb szintű készlet hely" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Az alkatrésznek értékesíthetőnek kell lennie" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "A tétel egy vevő rendeléshez foglalt" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "A tétel egy gyártási utasításhoz foglalt" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Vevő akihez rendeljük a készlet tételeket" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "A kiválasztott cég nem egy vevő" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Készlet hozzárendelés megjegyzései" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "A készlet tételek listáját meg kell adni" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Készlet összevonás megjegyzései" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Nem egyező beszállítók megengedése" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Nem egyező állapotok megjelenítése" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Legalább két készlet tételt meg kell adni" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Nincs változás" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Készlet tétel elsődleges kulcs értéke" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Készlettétel nincs készleten" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "Készlettétel már készleten van" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "Mennyiség nem lehet negatív" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Készlet tranzakció megjegyzései" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "Meglévő készletbe olvasztás" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 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:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Következő sorozatszám" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Előző Sorozatszám" @@ -9370,227 +9580,247 @@ msgstr "Token utolsó használata" msgid "Revoked" msgstr "Visszavonva" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Jogosultságok" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Nézet" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Jogosultság tételek megtekintéséhez" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Hozzáad" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Jogosultság tételek hozzáadásához" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Módosítás" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Jogosultság tételek szerkesztéséhez" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Törlés" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Jogosultság tételek törléséhez" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Robot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Belső" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Vendég" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Nyelv" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Felhasználó által preferált nyelv" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Téma" -#: users/models.py:514 +#: users/models.py:512 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:519 +#: users/models.py:517 msgid "Widgets" msgstr "Widgetek" -#: users/models.py:521 +#: users/models.py:519 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:528 +#: users/models.py:526 msgid "Display Name" msgstr "Megjelenítendő név" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Felhasználó választott megjelenítési neve" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Pozíció" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Fő munkakör vagy pozíció" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Felhasználói állapot üzenet" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Felhasználó földrajzi helye" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "A felhasználó éppen használja a rendszert" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Javasolt elérhetőségek" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Felhasználó típusa" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Milyen típusú ez a felhasználó?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Szervezet" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Felhasználó elsődleges szervezete/kötődése" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Elsődleges csoport" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Felhasználó elsődleges csoportja" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Adminisztrátor" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Beszerzési rendelések" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Vevői rendelések" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Visszavételek" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Felhasználónév" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Keresztnév" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "A felhasználó keresztneve" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Vezetéknév" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "A felhasználó vezetékneve" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "A felhasználó e-mail címe" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Személyzet" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Van-e a felhasználónak személyzeti jogosultsága" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Rendszergazda" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "A felhasználó rendszergazda-e" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Aktív a felhasználói fiók" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Csak rendszergazda szerkesztheti ezt a mezőt" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Jelszó" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Felhasználó jelszava" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Figyelmezetés felülbírálása" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "A jelszó szabályok figyelmeztetésének felülbírálata" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Nincs jogosultsága felhasználót létrehozni" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "A fiókod sikeresen létrejött." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 4aa801555e..028aec99e2 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint tidak ditemukan" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Daftar item atau filter harus disediakan untuk Pekerjaan Banyak" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Barang harus disediakan sebagai daftar" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Pengguna tidak memiliki izin untuk melihat model ini" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Jumlah yang diberikan tidak valid" @@ -112,13 +105,13 @@ msgstr "Masukkan tanggal" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Catatan" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "Nilai yang diberikan tidak sesuai dengan pola yang ditentukan: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Nomor seri kosong" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Gandakan Nomor Seri" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Tidak ada nomor seri ditemukan" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Hapus tag-tag HTML dari nilai ini" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Koneksi Galat" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Ukuran gambar terlalu besar" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "URL yang diberikan bukan file gambar yang valid" @@ -207,11 +216,11 @@ msgstr "URL yang diberikan bukan file gambar yang valid" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Surel" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Anda harus mengaktifkan autentikasi dua faktor sebelum melakukan hal lainnya." @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Pilihan tidak valid" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nama" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Keterangan" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Keterangan (opsional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Direktori" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Data Barcode" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Data barcode pihak ketiga" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash unik data barcode" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Sudah ada barcode yang sama" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Terjadi Kesalahan Server" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Sebuah kesalahan telah dicatat oleh server." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Harus berupa angka yang valid" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Mata Uang" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Nilai tidak valid" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL file gambar external" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Unduhan gambar dari URL external tidak aktif" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "Bukan kode mata uang yang valid" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Produksi Induk" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Bagian" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Pesanan harus dibatalkan sebelum dapat dihapus" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Order Produksi" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lokasi" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Order Produksi" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referensi Order Produksi" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referensi Order Produksi" msgid "Reference" msgstr "Referensi" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Pilih bagian untuk diproduksi" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referensi Order Penjualan" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Lokasi Sumber" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Lokasi Tujuan" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Pilih lokasi di mana item selesai akan disimpan" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Jumlah Produksi" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Jumlah item stok yang akan dibuat" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Item selesai" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Jumlah stok item yang telah diselesaikan" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Status pembuatan" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Kode status pembuatan" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Kode Kelompok" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Kode kelompok untuk hasil produksi ini" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Tanggal Pembuatan" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Target tanggal selesai" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Tanggal selesai" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "diselesaikan oleh" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Diserahkan oleh" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Pengguna yang menyerahkan order ini" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Penanggung Jawab" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Tautan eksternal" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Tautan menuju URL eksternal" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Tidak ada hasil produksi yang ditentukan" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Hasil produksi sudah selesai" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Hasil produksi tidak sesuai dengan order produksi" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Jumlah harus lebih besar daripada nol" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Jumlah" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Jumlah harus 1 untuk stok dengan nomor seri" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Item stok teralokasikan terlalu banyak" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Stok Item" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Sumber stok item" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Jumlah stok yang dialokasikan ke produksi" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Pasang ke" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Tujuan stok item" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Hasil Produksi" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Hasil produksi tidak sesuai dengan produksi induk" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Hasil bagian tidak sesuai dengan bagian dalam order produksi" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Hasil produksi ini sudah diselesaikan" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Hasil produksi tidak dialokasikan sepenuhnya" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Masukkan jumlah hasil pesanan" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Jumlah bagian yang dapat dilacak harus berupa angka bulat" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Nomor Seri" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Masukkan nomor seri untuk hasil pesanan" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Alokasikan nomor seri secara otomatis" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Alokasikan item yang diperlukan dengan nomor seri yang sesuai secara otomatis" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Nomor-nomor seri berikut sudah ada atau tidak valid" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Daftar hasil pesanan harus disediakan" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Lokasi hasil pesanan yang selesai" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Terima Alokasi Tidak Lengkap" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Tidak diizinkan" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Terima Tidak Teralokasikan" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Stok yang diperlukan belum teralokasikan sepenuhnya" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Terima Tidak Selesai" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Jumlah produksi yang diperlukan masih belum cukup" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Order memiliki hasil produksi yang belum dilengkapi" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Hasil produksi" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Hasil pesanan harus mengarah ke pesanan yang sama" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Item harus tersedia dalam stok" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Jumlah tersedia ({q}) terlampaui" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "Hasil produksi harus ditentukan untuk mengalokasikan bagian yang terlacak" -#: build/serializers.py:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Item yang dialokasikan harus disediakan" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Lokasi tidak termasuk" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Jangan ambil stok item dari lokasi yang dipilih" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Stok bergantian" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Item stok di beberapa lokasi dapat digunakan secara bergantian" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Stok pengganti" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Izinkan alokasi bagian pengganti" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Item tagihan material" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Dibatalkan" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Selesai" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Stok dibutuhkan untuk order produksi" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Pengguna" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Harga" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktif" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Judul" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Tautan" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Kesimpulan" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Berkas Gambar" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Lampiran" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "File tidak ditemukan" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Tautan eksternal tidak ditemukan" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Pilih file untuk dilampirkan" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Ukuran Berkas" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Terbuat" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Pilihan" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Aktif" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Respon" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Barang diterima" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nama File" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nama Perusahaan" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "Hari" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponen" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Aktifkan Laporan" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: 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:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" -msgstr "Surel diperlukan" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" +msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: 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:1012 -msgid "Group on signup" +#: common/setting/system.py:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1014 -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:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" -msgstr "Aktifkan Integrasi Antarmuka" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" +msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: common/setting/system.py:1105 +msgid "Enable plugins to respond to internal events" msgstr "" +#: common/setting/system.py:1111 +msgid "Enable interface integration" +msgstr "Aktifkan Integrasi Antarmuka" + #: common/setting/system.py:1112 -msgid "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Perusahaan" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Perusahaan" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Deskripsi Perusahaan" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Laman" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Nomor Ponsel" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontak alamat surel" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontak" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Kode Pos" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Tidak diketahui" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Selesai" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Total Harga" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Pelanggan" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Harga Jual" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Dikirim" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Jumlah yang dialokasikan harus lebih dari nol" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Order ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Salin Baris" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "Tolak" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Tanggal" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Harga Minimal" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Harga Maksimal" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Perbarui" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "Letter" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Nomor Seri" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Lampiran perlu diunggah untuk tes ini" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Ganti" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nama Pengguna" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Nama Depan" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Nama depan dari pengguna" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Nama Belakang" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Nama belakang dari pengguna" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Alamat surel dari pengguna" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Staf" - -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" + +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 5d5cf51e4c..72f0bcb43d 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Endpoint API non trovato" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "L'elenco degli articoli o dei filtri devono essere forniti per le operazioni di massa" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Gli articoli devono essere forniti come elenco" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Lista elementi fornita non valida" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "I filtri devono essere forniti come dizionario" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtri forniti non validi" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Tutti i filtri devono essere usati solo con true" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Nessun elemento corrisponde ai criteri forniti" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nessun dato fornito" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Questo campo deve essere unico." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "L'utente non ha i permessi per vedere questo modello" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Impossibile convertire {original} in {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Quantità inserita non valida" @@ -112,13 +105,13 @@ msgstr "Inserisci la data" msgid "Invalid decimal value" msgstr "Valore decimale non valido" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Note" @@ -131,75 +124,91 @@ msgstr "Il valore '{name}' non è nel formato del pattern" msgid "Provided value does not match required pattern: " msgstr "Il valore fornito non corrisponde al modello richiesto: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Impossibile serializzare più di 1000 elementi contemporaneamente" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Numero seriale vuoto" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Seriale Duplicato" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Gruppo non valido: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nessun numero di serie trovato" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Rimuovi i tag HTML da questo valore" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "I dati contengono un contenuto in markdown proibito" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Errore di connessione" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Il server ha risposto con un codice di stato non valido" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Si è verificata un'eccezione" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Il server ha risposto con valore Content-Length non valido" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Immagine troppo grande" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Il download dell'immagine ha superato la dimensione massima" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Il server remoto ha restituito una risposta vuota" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "L'URL fornito non è un file immagine valido" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Il campo deve corrispondere al modello richiesto" msgid "Reference number is too large" msgstr "Numero di riferimento troppo grande" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Scelta non valida" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descrizione" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descrizione (opzionale)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Percorso" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomi duplicati non possono esistere sotto lo stesso genitore" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Note di Markdown (opzionale)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Dati del Codice a Barre" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Dati Codice a Barre applicazioni di terze parti" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Codice a Barre" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Codice univoco del codice a barre" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Trovato codice a barre esistente" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Fallimento Attività" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Attività di lavoro in background '{f}' fallita dopo {n} tentativi" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Errore del server" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Un errore è stato loggato dal server." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Deve essere un numero valido" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Selezionare la valuta dalle opzioni disponibili" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Questo campo non può essere nullo." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valore non valido" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Immagine Remota" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL del file immagine remota" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Il download delle immagini da URL remoto non è abilitato" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Impossibile scaricare l'immagine dall'URL remoto" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Formato tipo di contenuto non valido" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Tipo di Contenuto non trovato" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Il tipo di contenuto non corrisponde alla classe mixin richiesta" @@ -537,11 +521,11 @@ msgstr "Cinese (Semplificato)" msgid "Chinese (Traditional)" msgstr "Cinese (Tradizionale)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Aggiornamento disponibile" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "È disponibile un aggiornamento per InvenTree" @@ -553,30 +537,30 @@ msgstr "Unità fisica non valida" msgid "Not a valid currency code" msgstr "Non è un codice valuta valido" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Stato dell'ordine" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Produzione Genitore" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Includi Varianti" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Includi Varianti" msgid "Part" msgstr "Articolo" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categoria" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Produzione Antenata" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Assegnato a me" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Assegnato a" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Creato prima" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Creato dopo" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Ha data d'inizio" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Data d'inizio prima" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Data d'inizio dopo" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Ha data di fine" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Data obiettivo prima" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Data obiettivo dopo" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Completato prima" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Completato dopo" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Data minima" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Data massima" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Escludi Albero" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "La produzione deve essere annullata prima di poter essere eliminata" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumabile" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opzionale" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Assemblaggio" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Monitorato" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testabile" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Ordine In Corso" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Allocato" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Utilizzato" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Ordinato" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordine di Produzione" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Posizione" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Output" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Ordini di Produzione" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Assembly BOM non è stato convalidato" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "L'utente o il gruppo responsabile deve essere specificato" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "L'ordine di costruzione della parte non può essere cambiata" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "La data di scadenza deve essere successiva alla data d'inizio" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Riferimento Ordine Di Produzione" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Riferimento Ordine Di Produzione" msgid "Reference" msgstr "Riferimento" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Breve descrizione della build (facoltativo)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "Ordine di produzione a cui questa produzione viene assegnata" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Selezionare parte da produrre" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Numero di riferimento ordine di vendita" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Ordine di vendita a cui questa produzione viene assegnata" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Posizione Di Origine" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Build Esterno" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Questo ordine di produzione è eseguito esternamente" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Posizione Della Destinazione" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Seleziona il luogo in cui gli articoli completati saranno immagazzinati" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Quantità Produzione" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Numero di articoli da costruire" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Articoli completati" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Numero di articoli di magazzino che sono stati completati" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Stato Produzione" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Codice stato di produzione" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Codice Lotto" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Codice del lotto per questa produzione" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Data di creazione" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Data inizio produzione" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Data d'inizio programmata per questo ordine di produzione" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Data completamento obiettivo" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Data di completamento" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "Completato da" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Rilasciato da" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Utente che ha emesso questo ordine di costruzione" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsabile" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Utente o gruppo responsabile di questo ordine di produzione" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Collegamento esterno" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link a URL esterno" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Priorità di produzione" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Priorità di questo ordine di produzione" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Codice del progetto" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Codice del progetto per questo ordine di produzione" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Impossibile finalizzare l'ordine di produzione con ordini secondari aperti" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Impossibile finalizzare l'ordine di produzione con articolo incompleti" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "L'ordine di produzione è stato completato" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Deve essere fornita un numero di serie per gli articoli rintracciabili" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nessun output di produzione specificato" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "La produzione è stata completata" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "L'output della produzione non corrisponde all'ordine di compilazione" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "La quantità deve essere maggiore di zero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "La quantità non può essere maggiore della quantità in uscita" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "La produzione non ha superati tutti i test richiesti" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "Impossibile completare parzialmente un build output con gli elementi assegnati" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Elemento di Riga Ordine di Produzione" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Crea oggetto" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantità" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Quantità richiesta per l'ordine di costruzione" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Quantità di articoli magazzino consumate" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "L'articolo in stock selezionato non corrisponde alla voce nella BOM" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "La quantità assegnata deve essere maggiore di zero" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "La quantità deve essere 1 per lo stock serializzato" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "L'articolo in giacenza è sovrallocato" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Articoli in magazzino" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Origine giacenza articolo" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Quantità di magazzino da assegnare per la produzione" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Installa in" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Destinazione articolo in giacenza" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Livello Produzione" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nome Articolo" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Genera Output" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "L'output generato non corrisponde alla produzione principale" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "L'output non corrisponde alle parti dell'ordine di produzione" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Questa produzione è stata già completata" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Questo output non è stato completamente assegnato" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Inserisci la quantità per l'output di compilazione" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Quantità totale richiesta per articoli rintracciabili" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Codice Seriale" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Inserisci i numeri di serie per gli output di compilazione (build option)" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Posizione dello stock per l'output della produzione" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Numeri di Serie Assegnazione automatica" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Assegna automaticamente gli articoli richiesti con i numeri di serie corrispondenti" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Deve essere fornito un elenco dei risultati di produzione" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Posizione dello stock per l'output di produzione rimosso" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Scarta Assegnazioni" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Scartare tutte le assegnazioni di magazzino per gli output rimossi" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Motivo dell'eliminazione degli output di compilazione" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Posizione per gli output di build completati" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Accetta Assegnazione Incompleta" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consuma Giacenze Allocate" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Rimuovi Output Incompleti" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Elimina gli output di produzione che non sono stati completati" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Non permesso" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Accetta come consumato da questo ordine di produzione" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Non assegnare prima di aver completato questo ordine di produzione" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Giacenza in eccesso assegnata" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Alcuni articoli di magazzino sono stati assegnati in eccedenza" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Accetta Non Assegnato" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "La giacenza richiesta non è stata completamente assegnata" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Accetta Incompleta" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "La quantità di produzione richiesta non è stata completata" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "L'ordine di costruzione ha ancora degli ordini di costruzione figli" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "L'ordine di costruzione deve essere in stato di produzione" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "L'ordine di produzione ha output incompleti" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linea di produzione" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Genera Output" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "L'output di produzione deve puntare alla stessa produzione" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Articolo linea di produzione" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "L'articolo deve essere disponibile" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Quantità disponibile ({q}) superata" -#: build/serializers.py:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Deve essere indicata l'allocazione dell'articolo" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Escludi Ubicazione" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Escludi gli elementi stock da questa ubicazione selezionata" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Scorte Intercambiabili" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Sostituisci Giacenze" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Consenti l'allocazione delle parti sostitutive" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Articoli Opzionali" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Assegna gli elementi opzionali della distinta base all'ordine di produzione" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Impossibile avviare l'attività di auto-allocazione" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Riferimento BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "Identificativo dell'Articolo BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nome Articolo BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Costruzione" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Articolo Fornitore" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Quantità assegnata" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Riferimento Ordine Di Costruzione" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Nome Categoria Articolo" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Tracciabile" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Ereditato" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Consenti Le Varianti" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Distinta base (Bom)" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "In Produzione" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Pianificato per la produzione" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Scorte esterne" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Disponibilità in magazzino" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Disponibili scorte alternative" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Disponibili varianti delle scorte" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "La quantità consumata supera la quantità assegnata" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Note facoltative per il consumo di magazzino" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "L'articolo prodotto deve puntare all'ordine di produzione corretto" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Duplica l'allocazione degli articoli da produrre" -#: build/serializers.py:1829 +#: build/serializers.py:1830 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:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Duplica l'allocazione della riga di produzione" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Deve essere fornita almeno un articolo o riga" @@ -1495,43 +1479,47 @@ msgstr "In Attesa" msgid "Cancelled" msgstr "Annullato" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Completo" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Giacenza richiesta per l'ordine di produzione" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "L'ordine di produzione {build} richiede articoli aggiuntivi" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Ordine di produzione in ritardo" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "L'ordine di produzione {bo} è in ritardo" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "È Un Connegamento" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "E' un file" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "L'utente non ha il permesso di eliminare questi allegati" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "L'utente non ha il permesso di eliminare questo allegato" @@ -1551,798 +1539,822 @@ msgstr "Nessun codice valuta valido fornito" msgid "No plugin" msgstr "Nessun plugin" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Etichetta Codice Progetto" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Aggiornato" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Orario dell'ultimo aggiornamento" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Aggiornato da" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Utente che per ultimo ha aggiornato questo oggetto" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Codice unico del progetto" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Descrizione del progetto" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Utente o gruppo responsabile di questo progetto" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Tasto impostazioni" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valore impostazioni" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Il valore specificato non è un opzione valida" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Il valore deve essere un valore booleano" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Il valore deve essere un intero" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Il valore deve essere un numero valido" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Il valore non supera i controlli di convalida" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "La stringa chiave deve essere univoca" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Utente" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Quantità prezzo limite" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Prezzo" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Prezzo unitario in quantità specificata" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Scadenza" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Scadenza in cui questa notifica viene ricevuta" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nome per questa notifica" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Attivo" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "È questa notifica attiva" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token per l'accesso" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Segreto" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Segreto condiviso per HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID Messaggio" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identificatore unico per questo messaggio" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Host da cui questo messaggio è stato ricevuto" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Intestazione" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Intestazione di questo messaggio" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Contenuto" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Contenuto di questo messaggio" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Scadenza in cui questo messaggio è stato ricevuto" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Lavorato il" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Il lavoro su questo messaggio è terminato?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titolo" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Collegamento" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Pubblicato" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autore" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Riepilogo" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Letto" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Queste notizie sull'elemento sono state lette?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "File immagine" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Tipo di modello di destinazione per questa immagine" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "ID modello di destinazione per questa immagine" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Unità Personalizzata" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Il simbolo dell'unità deve essere univoco" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Il nome dell'unità deve essere un identificatore valido" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nome dell'unità" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Simbolo" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Simbolo unità opzionale" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definizione" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definizione unità" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Allegato" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "File mancante" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Link esterno mancante" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Tipo modello" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Tipo di modello di destinazione per l'immagine" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Seleziona file da allegare" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Commento" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Commento allegato" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Data caricamento" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Data di caricamento del file" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Dimensione file" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Dimensioni file in byte" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Tipo di modello specificato per l'allegato non valido" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Stato Personalizzato" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Stati Personalizzati" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Imposta Stato Di Riferimento" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Set di stato esteso con questo stato personalizzato" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Chiave Logica" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valore" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Valore numerico che verrà salvato nel database dei modelli" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Nome dello Stato" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etichetta" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etichetta che verrà visualizzata nel frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Colore" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Colore che verrà visualizzato nel frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modello" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Modello a cui questo stato è associato" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Il modello deve essere selezionato" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "La chiave deve essere selezionata" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "La chiave logica deve essere selezionata" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "La chiave deve essere diversa dalla chiave logica" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Deve essere fornita una classe di stato di riferimento valida" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Elenco Selezioni" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Elenchi di Selezione" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Nome dell'elenco di selezione" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Descrizione della lista di selezione" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Bloccato" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Questa lista di selezione è bloccata?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Questo elenco di selezione può essere utilizzato?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Plugin Sorgente" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Plugin che fornisce l'elenco di selezione" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Stringa Sorgente" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Stringa opzionale che identifica il sorgente usato per questa lista" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Voce Predefinita" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Voce predefinita per questo elenco di selezione" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Creato" -#: common/models.py:2296 +#: common/models.py:2378 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:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Ultimo aggiornamento" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Voce Lista Selezione" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Voci Lista Selezione" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Elenco di selezione a cui appartiene questa voce" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Valore della voce della lista di selezione" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Etichetta per la voce elenco di selezione" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Descrizione della voce della lista di selezione" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Questa voce della lista di selezione è attiva?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Modello Parametro" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Modelli parametro" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "I parametri della casella di controllo non possono avere unità" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "I parametri della casella di controllo non possono avere scelte" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Le scelte devono essere uniche" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Il nome del modello del parametro deve essere univoco" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Tipo di modello di destinazione per questo modello di parametro" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nome Parametro" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unità" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Unità fisiche per questo parametro" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Descrizione del parametro" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Casella di spunta" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Questo parametro è una casella di spunta?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Scelte" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Scelte valide per questo parametro (separato da virgola)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Lista di selezione per questo parametro" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Abilitato" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Questo modello di parametro è abilitato?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Parametro" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Parametri" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Scelta non valida per il valore del parametro" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Tipo di modello specificato per parametro non valido" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "ID Modello" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "ID del modello di destinazione per questo parametro" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Modello" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Modello Parametro" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Dati" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Valore del Parametro" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Nota" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Note opzionali elemento" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Scansione Codice A Barre" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Dati del Codice a Barre" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Utente che ha scannerizzato il codice a barre" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Data e ora" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Data e ora della scansione del codice a barre" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Endpoint URL che ha elaborato il codice a barre" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contesto" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Dati contestuali per la scansione del codice a barre" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Risposta" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Dati di risposta dalla scansione del codice a barre" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Risultato" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "La scansione del codice a barre è riuscita?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Si è verificato un errore" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "Messaggio email" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "Messaggi email" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Annunciato" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Inviato" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Fallito" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Consegnato" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Confermato" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Ricevuti" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "In uscita" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Nessuna risposta" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Traccia La Consegna" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Conferma di lettura" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Tracciare i clic delle email" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "ID Globale" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID discussione" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Discussione" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Thread collegato a questo messaggio" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Priorità" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Discussione Email" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Discussioni Email" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Chiave" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Identificatore univoco per questa discussione" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Avviato internamente" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Questa discussione è iniziata internamente?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Data e ora in cui la discussione è stata creata" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Data e ora in cui la discussione è stata aggiornata" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Elemento ricevuto" @@ -2392,1235 +2404,1303 @@ msgstr "Indica se l'impostazione è sovrascritta da una variabile ambiente" msgid "Override" msgstr "Sovrascrivi" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "In Esecuzione" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Attività in sospeso" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Attività pianificate" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Attività Fallite" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID Attività" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ID attività univoco" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Blocco" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Tempo di blocco" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nome attività" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funzione" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nome della funzione" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argomenti" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argomenti attività" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argomenti Parole Chiave" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argomenti parole chiave attività" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nome del file" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Tipo di modello" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista di selezione bloccata" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Nessun gruppo" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "L'URL del sito è bloccato dalla configurazione" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Riavvio richiesto" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "È stata modificata un'impostazione che richiede un riavvio del server" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migrazioni in sospeso" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Numero di migrazioni del database in sospeso" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Codici di avviso attivi" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Un dizionario di codici di avviso attivi" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID istanza" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Identificatore unico per questa istanza InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Annuncio ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Annuncia l'ID dell'istanza del server nelle informazioni sullo stato del server (non autenticato)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nome Istanza Del Server" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Descrittore stringa per l'istanza del server" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Utilizza nome istanza" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Usa il nome dell'istanza nella barra del titolo" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Limita visualizzazione `Informazioni`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Mostra la modalità `Informazioni` solo ai superusers" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nome azienda" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nome interno dell'azienda" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL Base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL di base per l'istanza del server" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Valuta predefinita" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Selezionare la valuta di base per i calcoli dei prezzi" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Valute Supportate" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Elenco dei codici valuta supportati" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervallo Aggiornamento Valuta" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "giorni" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Plugin di aggiornamento della valuta" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Plugin di aggiornamento valuta da usare" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Scarica dall'URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Consenti il download di immagini e file remoti da URL esterno" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limite Dimensione Download" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Dimensione massima consentita per il download dell'immagine remota" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-agent utilizzato per scaricare dall'URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Consenti di sovrascrivere l'user-agent utilizzato per scaricare immagini e file da URL esterno (lasciare vuoto per il predefinito)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Convalida URL rigoroso" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Richiede specifico schema quando si convalidano gli URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Aggiorna intervallo di controllo" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Quanto spesso controllare gli aggiornamenti (impostare a zero per disabilitare)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Backup automatico" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Abilita il backup automatico di database e file multimediali" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervallo Di Backup Automatico" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Definisci i giorni intercorrenti tra un backup automatico e l'altro" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervallo Eliminazione Attività" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "I risultati delle attività in background verranno eliminati dopo un determinato numero di giorni" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervallo Di Cancellazione Registro Errori" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "I log di errore verranno eliminati dopo il numero specificato di giorni" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervallo Di Cancellazione Notifica" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Le notifiche dell'utente verranno eliminate dopo il numero di giorni specificato" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Intervallo Eliminazione Email" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "I messaggi e-mail verranno eliminati dopo il numero specificato di giorni" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Proteggi Log Email" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Impedisci l'eliminazione delle voci di log email" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Supporto Codice A Barre" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Abilita il supporto per lo scanner di codice a barre nell'interfaccia web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Memorizza Risultati Barcode" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Memorizza i risultati della scansione del codice a barre nel database" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Numero Massimo Scansioni Barcode" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Numero massimo di risultati della scansione del codice a barre da memorizzare" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Codice a barre inserito scaduto" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tempo di ritardo di elaborazione codice a barre" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Codice a Barre Supporto Webcam" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Consenti la scansione del codice a barre tramite webcam nel browser" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Visualizza dati codice a barre" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Visualizza i dati del codice a barre nel browser come testo" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Plugin Generazione Codice A Barre" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revisioni Articolo" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Abilita il campo revisione per l'articolo" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Solo revisione assemblaggio" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Consenti revisioni solo per articoli di assemblaggio" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Consenti l'eliminazione dall'assemblaggio" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Schema di espressione regolare per l'articolo corrispondente IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Consenti duplicati IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permetti a più articoli di condividere lo stesso IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Permetti modifiche al part number interno (IPN)" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copia I Dati Della distinta base dell'articolo" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copia I Dati Parametro dell'articolo" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copia I Dati dell'Articolo Test" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copia Template Parametri Categoria" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Gli articoli sono modelli per impostazione predefinita" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Componente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Acquistabile" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Vendibile" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Gli articoli sono tracciabili per impostazione predefinita" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuale" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Gli articoli sono virtuali per impostazione predefinita" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Mostra articoli correlati" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Visualizza parti correlate per ogni articolo" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Dati iniziali dello stock" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Dati iniziali del fornitore" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formato di visualizzazione del nome articolo" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formato per visualizzare il nome dell'articolo" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Icona predefinita Categoria Articolo" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Icona predefinita Categoria Articolo (vuoto significa nessuna icona)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Prezzi Minimi Decimali" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Prezzi Massimi Decimali" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Usa Prezzi Fornitore" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Ignora la Cronologia Acquisti" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Utilizzare i prezzi degli articoli in stock" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Età dei prezzi degli articoli in stock" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Utilizza Variazione di Prezzo" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Includi la variante dei prezzi nei calcoli dei prezzi complessivi" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Solo Varianti Attive" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Aggiornamento Automatico Prezzi" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervallo Di Ricostruzione Dei Prezzi" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Prezzi interni" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Abilita prezzi interni per gli articoli" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Sovrascrivi Prezzo Interno" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Abilita stampa etichette" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Abilita la stampa di etichette dall'interfaccia web" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Etichetta Immagine DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Abilita Report di Stampa" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Abilita generazione di report di stampa" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Modalità Debug" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Genera report in modalità debug (output HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Registro errori" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Errori di log che si verificano durante la generazione dei report" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Dimensioni pagina" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Dimensione predefinita della pagina per i report PDF" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forza Unità Parametro" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Seriali Unici Globali" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Elimina scorte esaurite" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Modello Codice a Barre" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Scadenza giacenza" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Abilita funzionalità di scadenza della giacenza" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vendi giacenza scaduta" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Consenti la vendita di stock scaduti" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Tempo di Scorta del Magazzino" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Crea giacenza scaduta" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Permetti produzione con stock scaduto" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Controllo della proprietà della giacenza" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Icona Predefinita Ubicazione di Magazzino" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Icona Predefinita Ubicazione di Magazzino (vuoto significa nessuna icona)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Mostra articoli a magazzino installati" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Visualizza gli articoli a magazzino installati nelle tabelle magazzino" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Verificare la distinta base durante l'installazione degli articoli" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Consenti trasferimento magazzino esaurito" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Modello Di Riferimento Ordine Di Produzione" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "È richiesto il Proprietario Responsabile" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "A ogni ordine deve essere assegnato un proprietario responsabile" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Richiede Articolo Attivo" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Impedisci la creazione di ordini di produzione per gli articolo inattivi" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Richiede Articolo Bloccato" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Impedisci la creazione di ordini di costruzione per le parti sbloccate" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Richiede un BOM valido" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Richiedi Ordini Dei Figli Chiusi" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Ordini di Produzione Esterni" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Abilita funzionalità ordini di produzione esterni" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blocca Fino Al Passaggio Dei Test" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Abilita Ordini Di Reso" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Abilita la funzionalità ordine di reso nell'interfaccia utente" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Motivo di Riferimento per ordine di reso" -#: common/setting/system.py:825 +#: common/setting/system.py:846 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:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Modifica Ordini Di Reso Completati" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Modello Di Riferimento Ordine Di Vendita" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Spedizione Predefinita Ordine Di Vendita" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Abilita la creazione di spedizioni predefinite con ordini di vendita" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Modifica Ordini Di Vendita Completati" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "La Spedizione Richiede Controllo" -#: common/setting/system.py:873 +#: common/setting/system.py:894 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:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Segna gli ordini spediti come completati" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Modello di Riferimento Ordine D'Acquisto" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Modifica Ordini Di Acquisto Completati" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Converti Valuta" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Completa Automaticamente Gli Ordini D'Acquisto" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Abilita password dimenticata" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Abilita la funzione password dimenticata nelle pagine di accesso" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Abilita registrazione" -#: common/setting/system.py:931 +#: common/setting/system.py:960 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSO abilitato" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Abilita SSO nelle pagine di accesso" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Abilita registrazione SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Abilita sincronizzazione dei gruppi SSO" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Chiave gruppo SSO" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Mappa del gruppo SSO" -#: common/setting/system.py:966 +#: 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 "Una mappatura dai gruppi SSO ai gruppi InvenTree locali. Se il gruppo locale non esiste, verrà creato." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Rimuovere i gruppi al di fuori dell'SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email richiesta" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Richiedi all'utente di fornire una email al momento dell'iscrizione" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Riempimento automatico degli utenti SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Posta due volte" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Password due volte" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Domini consentiti" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Gruppo iscrizione" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Applica MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Gli utenti devono utilizzare la sicurezza a due fattori." -#: common/setting/system.py:1026 +#: 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 "Abilitare questa impostazione richiederà a tutti gli utenti di impostare l'autenticazione multi fattore. Tutte le sessioni saranno disconnesse immediatamente." -#: common/setting/system.py:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Controlla i plugin all'avvio" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Controlla gli aggiornamenti dei plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Abilita controlli periodici per gli aggiornamenti dei plugin installati" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Abilita l'integrazione URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Attiva plugin per aggiungere percorsi URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Attiva integrazione navigazione" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Abilita i plugin per l'integrazione nella navigazione" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Abilita l'app integrata" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Abilita plugin per aggiungere applicazioni" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Abilita integrazione pianificazione" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Abilita i plugin per eseguire le attività pianificate" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Abilita eventi integrati" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Abilita plugin per rispondere agli eventi interni" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Abilita integrazione interfaccia" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Abilita i plugin per l'integrazione nell'interfaccia utente" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Abilita integrazione email" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Abilita i plugin per elaborare le email in uscita/in arrivo" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Abilita codici progetto" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Abilita i codici del progetto per tracciare i progetti" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Escludi Posizioni Esterne" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Inventario periodico automatico" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Visualizza i nomi completi degli utenti" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Mostra nomi completi degli utenti invece che nomi utente" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Visualizza Profili Utente" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Visualizza i profili degli utenti sulla pagina del loro profilo" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Abilita Dati Stazione Di Prova" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Abilita Ping Macchina" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 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" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Ricevi segnalazioni di errore" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Ricevi notifiche per errori di sistema" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Ultime stampanti usate" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "Salva le ultime stampanti usate da un'utente" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Tutti i modelli" @@ -3965,365 +4061,369 @@ msgstr "L'articolo è attivo" msgid "Manufacturer is Active" msgstr "Il produttore è attivo" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "L'articolo fornitore è attivo" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "L'articolo interno è attivo" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Il fornitore è attivo" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Produttore" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Azienda" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Ha Scorte" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Aziende" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Descrizione azienda" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Descrizione dell'azienda" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Sito Web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Sito web aziendale" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefono" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Numero di telefono di contatto" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Indirizzo email" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contatto" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Punto di contatto" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Collegamento alle informazioni aziendali esterne" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Questa azienda è attiva?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "È un cliente" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Vendi oggetti a questa azienda?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "È un fornitore" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Acquistate articoli da questa azienda?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "È un produttore" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Questa azienda produce articoli?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Valuta predefinita utilizzata per questa azienda" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "Partita IVA" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "Codice Fiscale Azienda" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Indirizzo" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Indirizzi" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Seleziona azienda" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Titolo indirizzo" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Titolo che descrive la voce indirizzo" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Indirizzo Principale" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Imposta come indirizzo primario" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Linea 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Indirizzo (linea 1)" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Linea 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Indirizzo (linea 2)" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "CAP" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Città/Regione" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Codice postale città/regione" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Stato/Provincia" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Stato o provincia" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Nazione" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Indirizzo Paese" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Note di spedizione del corriere" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Note per il corriere di spedizione" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Note di spedizione interne" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Note di spedizione per uso interno" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Collegamento alle informazioni sull'indirizzo (esterno)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Codice articolo produttore" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Articolo di base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Seleziona articolo" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Seleziona Produttore" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "Codice articolo produttore (MPN)" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Codice articolo produttore" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL dell'articolo del fornitore" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Descrizione articolo costruttore" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Le unità del pacchetto devono essere maggiori di zero" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "L'articolo del costruttore collegato deve riferirsi alla stesso articolo" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornitore" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Seleziona fornitore" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unità di giacenza magazzino fornitore" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Questo articolo fornitore è attivo?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Selezionare un produttore" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL dell'articolo del fornitore" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Descrizione articolo fornitore" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "costo base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Onere minimo (ad esempio tassa di stoccaggio)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Confezionamento" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Imballaggio del pezzo" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Quantità Confezione" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "multiplo" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Ordine multiplo" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Quantità disponibile dal fornitore" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilità Aggiornata" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Data dell’ultimo aggiornamento dei dati sulla disponibilità" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Sconto Prezzo Fornitore" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Valuta predefinita utilizzata per questo fornitore" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Nome Azienda" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "In magazzino" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Sconti a scalare" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Errore durante l'esportazione dei dati" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Identificatore del database esistente per il record" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "La colonna è già mappata a un campo del database" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Il campo è già mappato a una colonna di dati" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "La colonna non esiste nel file dati" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Il campo non esiste nel modello di destinazione" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Il campo selezionato è di sola lettura" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Sessione d'importazione" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Campo" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Colonna" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Indice riga" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Dati riga originali" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Errori" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Valido" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "L'ID è richiesto per aggiornare i record esistenti." -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Nessun record trovato con l'ID fornito" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Formato ID fornito non valido" @@ -4588,7 +4688,7 @@ msgstr "Numero di copie da stampare per ogni etichetta" msgid "Connected" msgstr "Connesso" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Sconosciuto" @@ -4692,7 +4792,7 @@ msgstr "Chiave della proprietà" msgid "Value of the property" msgstr "Valore della proprietà" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Gruppo" @@ -4720,7 +4820,7 @@ msgstr "Valore massimo per il tipo di avanzamento, richiesto se tipo = progresso msgid "Order Reference" msgstr "Riferimento ordine" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "In Sospeso" @@ -4728,7 +4828,7 @@ msgstr "In Sospeso" msgid "Has Project Code" msgstr "Ha il codice del progetto" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Creato Da" @@ -4764,57 +4864,69 @@ msgstr "Data obiettivo prima" msgid "Target Date After" msgstr "Data obiettivo dopo" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Prezzo Articolo" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Completato prima" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Completato dopo" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Ordine di Produzione Esterno" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Ordine" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Ordine completato" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Articolo interno" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Ordine in sospeso" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Completato" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Ha Spedizione" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Ordine D'Acquisto" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Ordine D'Acquisto" msgid "Sales Order" msgstr "Ordini di Vendita" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Prezzo Totale" msgid "Total price for this order" msgstr "Prezzo totale dell'ordine" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Valuta ordine" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Valuta per questo ordine (lasciare vuoto per usare il valore predefinito msgid "This order is locked and cannot be modified" msgstr "Questo ordine è bloccato e non può essere modificato" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Il contatto non corrisponde all'azienda selezionata" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "La data d'inizio deve essere precedente alla data di fine" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "L'indirizzo non corrisponde all'azienda selezionata" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Descrizione dell'ordine (opzionale)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Seleziona il codice del progetto per questo ordine" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Collegamento a un sito web esterno" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Data iniziale" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Data d'inizio programmata per questo ordine" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data scadenza" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Data di emissione" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Data di emissione ordine" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Utente o gruppo responsabile di questo ordine" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Punto di contatto per questo ordine" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Indirizzo dell'azienda per questo ordine" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Riferimento ordine" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Stato" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Stato ordine d'acquisto" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Azienda da cui sono stati ordinati gli articoli" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Riferimento fornitore" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Codice di riferimento ordine fornitore" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "ricevuto da" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Data ordine completato" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destinazione" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Destinazione per gli elementi ricevuti" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Il fornitore dell'articolo deve corrispondere al fornitore dell'ordine di produzione" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "L'elemento di riga non corrisponde all'ordine di acquisto" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Manca un elemento collegato" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "La quantità deve essere un numero positivo" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Azienda da cui sono stati ordinati gli elementi" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Stato ordine di vendita" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Riferimento Cliente " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Codice di riferimento Ordine del Cliente" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Data di spedizione" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "spedito da" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "L'ordine è già stato completato" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "L'ordine è già stato annullato" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Solo un ordine aperto può essere contrassegnato come completo" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "L'ordine è bloccato e non può essere modificato" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Quantità Elementi" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Riferimento Linea Elemento" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Note linea elemento" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Descrizione della parte (opzionale)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contesto aggiuntivo per questa voce" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Prezzo unitario" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Riga ordine d'acquisto" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "L'articolo del fornitore deve corrispondere al fornitore" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "L'ordine di produzione deve essere contrassegnato come esterno" -#: order/models.py:1904 +#: order/models.py:1971 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:1910 +#: order/models.py:1977 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:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Articolo Fornitore" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Ricevuto" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Numero di elementi ricevuti" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Prezzo di Acquisto" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Prezzo di acquisto unitario" -#: order/models.py:1978 +#: order/models.py:2056 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:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Riga Extra ordine di acquisto" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Articolo ordine di vendita" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Prezzo di Vendita" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Prezzo unitario di vendita" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Spedito" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Quantità spedita" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Spedizione dell'ordine di vendita" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "L'indirizzo di spedizione deve corrispondere al cliente" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Indirizzo di consegna per questa spedizione" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Data di spedizione" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Data di consegna" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Data di consegna della spedizione" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Verificato Da" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Utente che ha controllato questa spedizione" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Spedizione" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Numero di spedizione" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Numero di monitoraggio" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informazioni di monitoraggio della spedizione" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Numero Fattura" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Numero di riferimento per la fattura associata" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "La spedizione è già stata spedita" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "La spedizione non ha articoli di stock assegnati" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "La spedizione deve essere controllata prima che possa essere completata" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Riga Extra ordine di vendita" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Assegnazione Ordini Di Vendita" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "L'elemento di magazzino non è stato assegnato" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Impossibile allocare stock a una riga senza un articolo" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La quantità di ripartizione non puo' superare la disponibilità della giacenza" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "La quantità di assegnazione deve essere maggiore di zero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "La quantità deve essere 1 per l'elemento serializzato" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "L'ordine di vendita non corrisponde alla spedizione" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "La spedizione non corrisponde all'ordine di vendita" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Linea" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Riferimento della spedizione ordine di vendita" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Elemento" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Seleziona elemento stock da allocare" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Inserisci la quantità assegnata alla giacenza" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Riferimento ordine di reso" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Società a cui vengono restituiti gli articoli" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Stato ordine di reso" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Articolo Linea Ordine Reso" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "L'elemento stock deve essere specificato" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Quantità di reso superiore alla quantità di scorta" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "La quantità di reso deve essere maggiore di zero" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Quantità non valida per l'elemento stock serializzato" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Seleziona l'elemento da restituire dal cliente" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Data di ricezione" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "La data in cui questo articolo restituito è stato ricevuto" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Risultati" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Risultato per questa voce di riga" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Riga Extra ordine di reso" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID Ordine" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID dell'ordine da duplicare" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Copia Linee" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Copia gli elementi di riga dall'ordine originale" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Copia Linee Extra" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Elementi Riga" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Righe Completate" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplica Ordine" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Specifica le opzioni per duplicare questo ordine" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "ID dell'ordine non corretto" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Nome Fornitore" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "L'ordine non può essere cancellato" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Consenti di chiudere l'ordine con elementi di riga incompleti" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "L'ordine ha elementi di riga incompleti" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "L'ordine non è aperto" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Prezzo Automatico" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Valuta prezzo d'acquisto" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Unisci elementi" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Codice articolo" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Numero Dell'articolo Interno" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Numero Articolo Interno" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "L'articolo del fornitore deve essere specificato" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "L'ordine di acquisto deve essere specificato" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Il fornitore deve essere abbinato all'ordine d'acquisto" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "L'ordine di acquisto deve essere abbinato al fornitore" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Elemento Riga" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Seleziona la posizione di destinazione per gli elementi ricevuti" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Inserisci il codice univoco per gli articoli in arrivo" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Data di Scadenza" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Inserisci la data di scadenza per gli articoli in arrivo" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Inserisci i numeri di serie per gli articoli stock in arrivo" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Sovrascrivi le informazioni d'imballaggio per gli articoli in arrivo" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Nota aggiuntiva per gli articoli in arrivo" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Codice a Barre" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Codice a barre scansionato" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Il codice a barre è già in uso" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Gli elementi di linea devono essere forniti" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "La destinazione deve essere specificata" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "I valori dei codici a barre forniti devono essere univoci" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Spedizioni" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Spedizioni Completate" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Valuta prezzo di vendita" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Elementi Assegnati" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nessun dettaglio di spedizione fornito" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "La quantità deve essere positiva" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Inserisci i numeri di serie da assegnare" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "La spedizione è già stata spedita" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "La spedizione non è associata con questo ordine" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "I seguenti numeri di serie non sono disponibili" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Articoli Linea Ordine Reso" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "L'elemento di riga non corrisponde all'ordine di reso" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "L'elemento di riga è già stato ricevuto" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Quantità da restituire" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Valuta del prezzo" @@ -5598,146 +5742,150 @@ msgstr "Rimborso" msgid "Reject" msgstr "Rifiuta" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Ordine D'Acquisto in ritardo" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "L'ordine d'acquisto {po} è in ritardo" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Ordini Di Vendita in ritardo" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "L'ordine di vendita {so} è ora in ritardo" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Ordini di Reso in Ritardo" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "L'ordine di reso {ro} è ora in ritardo" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Preferiti" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filtra per categorie preferite" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Profondità" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtra per profondità categoria" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Livello principale" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtra per categorie di primo livello" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Cascata" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Includi sottocategorie nei risultati filtrati" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Genitore" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filtra per categoria genitore" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Escludi sottocategorie sotto la categoria specificata" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Ha Risultati" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "È una Variante" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "E' una revisione" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Ha revisioni" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "BOM Valido" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Categorie a Cascata" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filtra per categoria ID numerica o per la stringa 'null'" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "L'articolo assemblato è provabile" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Il componente è provabile" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Utilizzi" @@ -5746,11 +5894,11 @@ msgstr "Utilizzi" msgid "Part Category" msgstr "Categoria Articoli" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Categorie Articolo" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Posizione Predefinita" @@ -5778,7 +5926,7 @@ msgstr "Parole chiave predefinite per gli articoli in questa categoria" msgid "Icon" msgstr "Icona" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Icona (facoltativa)" @@ -5799,1025 +5947,1050 @@ msgstr "Valore Predefinito" msgid "Default Parameter Value" msgstr "Valore Parametro Predefinito" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Articoli" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Impossibile eliminare i parametri di una parte bloccata" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Impossibile modificare i parametri di una parte bloccata" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Impossibile eliminare questo articolo perché è bloccato" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Impossibile eliminare questo articolo perché è ancora attivo" -#: part/models.py:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN deve corrispondere al modello regex {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "L'articolo non può essere una revisione di se stesso" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Non puoi fare la revisione di un articolo che è già una revisione" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Il codice di revisione deve essere specificato" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Le revisioni sono consentite solo per le parti di assemblaggio" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Non è possibile effettuare la revisione di un articolo modello" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "L'articolo genitore deve puntare allo stesso modello" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Esiste già un elemento stock con questo numero seriale" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Non è consentito duplicare IPN nelle impostazioni dell'articolo" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "La revisione dell'articolo duplicata esiste già." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Un articolo con questo Nome, IPN e Revisione esiste già." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Gli articoli non possono essere assegnati a categorie articolo principali!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nome articolo" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "È Template" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Quest'articolo è un articolo di template?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Questa parte è una variante di un altro articolo?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante Di" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Descrizione della parte (opzionale)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Parole Chiave" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Parole chiave per migliorare la visibilità nei risultati di ricerca" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Categoria articolo" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN - Numero di riferimento interno" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Numero di revisione o di versione" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisione" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Questo articolo è una revisione di un altro articolo?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Revisione di" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Dove viene normalmente immagazzinato questo articolo?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Scadenza Predefinita" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Scorta Minima" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Livello minimo di giacenza consentito" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Unita di misura per questo articolo" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Questo articolo può essere costruito da altri articoli?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Questo articolo può essere utilizzato per costruire altri articoli?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Questo articolo ha il tracciamento per gli elementi unici?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Questo articolo può avere delle prove registrate?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Quest'articolo può essere acquistato da fornitori esterni?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Questo pezzo può essere venduto ai clienti?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Quest'articolo è attivo?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Gli articoli bloccati non possono essere modificati" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "BOM Convalidata" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Il BOM per questa parte è valido?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Somma di controllo Distinta Base" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Somma di controllo immagazzinata Distinta Base" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Distinta Base controllata da" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Data di verifica Distinta Base" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Creazione Utente" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Utente responsabile di questo articolo" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Vendita multipla" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Valuta utilizzata per calcolare i prezzi" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Costo Minimo Distinta Base" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Costo minimo dei componenti dell'articolo" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Costo Massimo Distinta Base" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Costo massimo dei componenti dell'articolo" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Importo Acquisto Minimo" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Costo minimo di acquisto storico" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Importo massimo acquisto" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Costo massimo di acquisto storico" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Prezzo Interno Minimo" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Costo minimo basato su interruzioni di prezzo interne" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Prezzo Interno Massimo" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Costo massimo basato su interruzioni di prezzo interne" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Prezzo Minimo Fornitore" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Prezzo minimo articolo da fornitori esterni" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Prezzo Massimo Fornitore" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Prezzo massimo dell'articolo proveniente da fornitori esterni" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Variazione di costo minimo" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Costo minimo calcolato di variazione dell'articolo" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Massima variazione di costo" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Costo massimo calcolato di variazione dell'articolo" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Costo Minimo" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Sovrascrivi il costo minimo" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Costo Massimo" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Sovrascrivi il costo massimo" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Costo minimo totale calcolato" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Costo massimo totale calcolato" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Prezzo Di Vendita Minimo" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Prezzo minimo di vendita basato sulle interruzioni di prezzo" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Prezzo Di Vendita Massimo" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Prezzo massimo di vendita basato sulle interruzioni di prezzo" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Costo Di Vendita Minimo" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Prezzo storico minimo di vendita" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Costo Di Vendita Minimo" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Prezzo storico massimo di vendita" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Articolo per l'inventario" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Contatore Elemento" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Numero di scorte individuali al momento dell'inventario" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Totale delle scorte disponibili al momento dell'inventario" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Data" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Data in cui è stato effettuato l'inventario" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Costo Minimo Scorta" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Costo minimo stimato di magazzino a disposizione" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Costo Massimo Scorte" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Costo massimo stimato di magazzino a disposizione" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Aggiungi Prezzo Ribassato di Vendita dell'Articolo" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Modello Prove Articolo" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nome Test" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Inserisci un nome per la prova" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Chiave Di Prova" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Chiave semplificata per la prova" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Descrizione Di Prova" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Inserisci descrizione per questa prova" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Questo test è attivo?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Richiesto" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Questa prova è necessaria per passare?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Valore richiesto" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Allegato Richiesto" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Scelte valide per questo test (separate da virgole)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 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:3961 +#: part/models.py:4030 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:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Seleziona articolo principale" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Articolo subordinato" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Seleziona l'articolo da utilizzare nella Distinta Base" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Quantità Distinta Base per questo elemento Distinta Base" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Questo elemento della Distinta Base è opzionale" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Imposta quantità" -#: part/models.py:4014 +#: part/models.py:4091 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:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Logoramento" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Arrotondamento Multiplo" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Riferimento Elemento Distinta Base" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Note Elemento Distinta Base" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Codice di controllo" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Codice di controllo Distinta Base" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Convalidato" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Questo articolo della distinta base è stato validato" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Viene Ereditato" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "La quantità deve essere un valore intero per gli articoli rintracciabili" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "L'articolo subordinato deve essere specificato" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Elemento Distinta Base Sostituito" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Elemento principale Distinta Base" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Sostituisci l'Articolo" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Articolo 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Articolo 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Seleziona Prodotto Relativo" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Nota per questa relazione" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "La relazione duplicata esiste già" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Categoria Superiore" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Categoria articolo principale" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Sottocategorie" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Risultati" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Numero di risultati registrati rispetto a questo modello" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Valuta di acquisto di questo articolo in stock" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Il file non è un immagine" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Articolo Originale" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Seleziona l'articolo originale da duplicare" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Copia immagine" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Copia immagine dall'articolo originale" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copia Distinta Base" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Copia fattura dei materiali dall'articolo originale" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Copia parametri" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Copia i dati dei parametri dall'articolo originale" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Copia note" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Copia note dall'articolo originale" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Copia Test" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "Copia modelli di test dall'articolo originale" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Quantità iniziale" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Ubicazione Iniziale Magazzino" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Specificare l'ubicazione iniziale del magazzino per questo Articolo" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Seleziona il fornitore (o lascia vuoto per saltare)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleziona il produttore (o lascia vuoto per saltare)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Codice articolo Produttore" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "L'azienda selezionata non è un fornitore valido" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "L'azienda selezionata non è un produttore valido" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "L'articolo del produttore che corrisponde a questo MPN esiste già" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "L'articolo del fornitore che corrisponde a questo SKU esiste già" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Nome Categoria" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "In Costruzione" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Quantità di questo articolo attualmente in produzione" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Eccezionale quantità di questa parte prevista da costruire" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Articoli in magazzino" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revisioni" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Giacenze Totali" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Scorte Non Assegnate" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Scorta Variante" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Duplica articolo" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Copia i dati iniziali da un altro Articolo" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Stock iniziale" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Crea Articolo con quantità di scorta iniziale" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Informazioni Fornitore" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Aggiungi le informazioni iniziali del fornitore per questo articolo" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Copia Parametri Categoria" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Copia i parametri dai modelli della categoria articolo selezionata" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Immagine esistente" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Nome del file di un'immagine articolo esistente" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Il file immagine non esiste" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Convalida l'intera Fattura dei Materiali" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Puoi produrre" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Richiesto per gli Ordini di Produzione" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Assegnato agli Ordini di Produzione" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Richiesto per gli Ordini di Vendita" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Assegnato agli Ordini di Vendita" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Prezzo Minimo" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Sovrascrivi valore calcolato per il prezzo minimo" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Valuta del prezzo minimo" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Prezzo Massimo" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Sovrascrivi valore calcolato per il prezzo massimo" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Valuta del prezzo massimo" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Aggiorna" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Aggiorna i prezzi per questo articolo" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Il prezzo minimo non può essere maggiore del prezzo massimo" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Il prezzo massimo non può essere minore del prezzo minimo" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Seleziona l'assemblaggio padre" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Seleziona la componente" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Seleziona l'articolo da cui copiare la distinta base" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Rimuovi Dati Esistenti" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Rimuovi elementi distinta base esistenti prima di copiare" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Includi Ereditato" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Includi gli elementi Distinta Base ereditati da prodotti template" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Salta Righe Non Valide" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Abilita questa opzione per saltare le righe non valide" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Copia Articoli sostitutivi" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Copia articoli sostitutivi quando duplichi gli elementi distinta base" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notifica di magazzino bassa" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Notifica di magazzino" -#: part/tasks.py:77 +#: part/tasks.py:78 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:79 +#: part/tasks.py:80 #, 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:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Nessuna data di scadenza." -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "Scaduto {abs(days_diff)} giorni fa" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Scade oggi" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} giorni" @@ -7031,15 +7204,15 @@ msgstr "Quantità da assegnare" msgid "Label printing failed" msgstr "Stampa etichetta fallita" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Errore nel rendering dell'etichetta in PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Errore nel rendering dell'etichetta in HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Nessun elemento fornito da stampare" @@ -7100,7 +7273,7 @@ msgstr "Fornisce supporto nativo per codici a barre" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Modalità debug" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "Bordo" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Orizzontale" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "L'installazione dei plugin è disattivata" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin installato con successo" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin installato in {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nessun autore trovato" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "Installazione non confermata" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nome modello" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Descrizione del template" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Allega al Modello su Stampa" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Formato del nome file" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtri" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Larghezza [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Larghezza dell'etichetta, specificata in mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Altezza [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Larghezza dell'etichetta, specificata in mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Snippet" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Report file snippet" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Descrizione file snippet" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Risorsa" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Report file risorsa" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "File risorsa descrizione" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numero Seriale" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Elementi installati" @@ -8248,184 +8438,196 @@ msgstr "Nessun risultato (richiesto)" msgid "No result" msgstr "Nessun risultato" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "File immagine non trovato" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Nome della parte (maiuscole e minuscole)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Il nome della parte contiene (maiuscole e minuscole)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Nome della parte (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "IPN della parte (maiuscole e minuscole)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "IPN della parte contiene (maiuscole e minuscole)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "IPN della parte (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Giacenza minima" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Giacenza massima" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Codici di stato" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Ubicazione Esterna" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Obsoleto" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "La quantità è richiesta" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Deve essere fornita un articolo valido" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Ubicazione magazzino" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Posizioni magazzino" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Proprietario" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Seleziona Owner" @@ -8461,7 +8663,7 @@ msgstr "Seleziona Owner" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Esterno" @@ -8481,274 +8683,282 @@ msgstr "" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "L'articolo deve essere specificato" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Non è possibile creare un elemento di magazzino per articoli virtuali" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "L'elemento non può appartenere a se stesso" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Elemento di magazzino principale" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Articolo base" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Seleziona un fornitore articolo corrispondente per questo elemento di magazzino" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Dove si trova questo articolo di magazzino?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Imballaggio di questo articolo di magazzino è collocato in" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Installato In" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Questo elemento è stato installato su un altro elemento?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Numero di serie per questo elemento" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Codice lotto per questo elemento di magazzino" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Quantità disponibile" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Genera Costruzione" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Costruisci per questo elemento di magazzino" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Origina Ordine di Acquisto" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Ordine d'acquisto per questo articolo in magazzino" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Destinazione Ordine di Vendita" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Elimina al esaurimento" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Cancella questo Elemento di Magazzino quando la giacenza è esaurita" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Prezzo di acquisto unitario al momento dell’acquisto" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Convertito in articolo" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "L'articolo non è impostato come tracciabile" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "La quantità deve essere un numero intero" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "I numeri di serie devono essere forniti come elenco" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "La quantità non corrisponde ai numeri di serie" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 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:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "L'elemento di magazzino è installato in un altro elemento" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "L'elemento di magazzino contiene altri elementi" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "L'elemento di magazzino è stato assegnato a un cliente" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "L'elemento di magazzino è attualmente in produzione" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Il magazzino serializzato non può essere unito" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Duplica elementi di magazzino" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Gli elementi di magazzino devono riferirsi allo stesso articolo" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Gli elementi di magazzino devono riferirsi allo stesso articolo fornitore" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "I codici di stato dello stock devono corrispondere" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "Le giacenze non possono essere spostate perché non disponibili" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Note d'ingresso" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Il valore deve essere fornito per questo test" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "L'allegato deve essere caricato per questo test" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Risultato Test" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Test valore output" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Risultato della prova allegato" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Note del test" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Elemento principale" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Inserisci i numeri di serie per i nuovi elementi" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Scaduto" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Elementi secondari" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Inserisci il numero di elementi di magazzino da serializzare" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Posizione magazzino di destinazione" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Numeri di serie non possono essere assegnati a questo articolo" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Numeri di serie già esistenti" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Seleziona elementi di magazzino da installare" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Aggiungi nota di transazione (opzionale)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Elemento di magazzino non disponibile" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "L'articolo selezionato non è nella Fattura dei Materiali" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Posizione di destinazione per gli elementi disinstallati" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sottoallocazioni" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "L'articolo deve essere vendibile" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "L'elemento è assegnato a un ordine di vendita" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Elemento assegnato a un ordine di costruzione" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Cliente a cui assegnare elementi di magazzino" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "L'azienda selezionata non è un cliente" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Note sull'assegnazione delle scorte" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Deve essere fornito un elenco degli elementi di magazzino" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Note di fusione di magazzino" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Consenti fornitori non corrispondenti" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Consenti stato non corrispondente" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Devono essere riforniti almeno due elementi in magazzino" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Nessun cambiamento" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Valore di chiave primaria StockItem" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Note sugli spostamenti di magazzino" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "Revocato" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Impostazione autorizzazioni" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Visualizza" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Autorizzazione a visualizzare gli articoli" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Aggiungi" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Autorizzazione ad aggiungere elementi" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Modificare" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Permessi per modificare gli elementi" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Elimina" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Autorizzazione ad eliminare gli elementi" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Bot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Interno" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Ospite" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Lingua" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Lingua preferita dell'utente" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Tema" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "Widgets" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Nome Visualizzato" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Amministratore" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Ordine di acquisto" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Ordini di Vendita" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Ordini di reso" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nome utente" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Nome" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Nome dell'utente" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Cognome" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Cognome dell'utente" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Indirizzo email dell'utente" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Questo utente ha i permessi dello staff" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superuser" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Questo utente è un superutente" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Questo account utente è attivo" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Il tuo account è stato creato." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Si prega di utilizzare la funzione di reimpostazione password per accedere" -#: users/serializers.py:452 +#: users/serializers.py:497 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 db831f26b4..6dcbe5868d 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "APIエンドポイントが見つかりません" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "バルク運転には、品目またはフィルターのリストが必要です" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "項目はリストとして提供されなければなりません" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "無効なアイテムリスト" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "フィルタはディクショナリとして提供されなければなりません" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "提供されたフィルタが無効" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "すべてのフィルターは真の場合にのみ使用されなければならない" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "指定された条件に一致する項目がありません" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "データの提供がありません。" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "この項目は一意である必要があります。" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "ユーザーにこのモデルを表示する権限がありません" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "{original}を{unit}に変換できませんでした。" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "数量コードが無効です" @@ -112,13 +105,13 @@ msgstr "日付を入力する" msgid "Invalid decimal value" msgstr "無効な10進数値" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "メモ" @@ -131,75 +124,91 @@ msgstr "値 '{name}' はパターン形式で表示されません" msgid "Provided value does not match required pattern: " msgstr "指定された値が必要なパターンと一致しません: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "一度に1000以上のアイテムをシリアライズすることはできません。" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "シリアル番号は空です" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "重複シリアル" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "無効なグループです:{group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "グループ範囲 {group} が許容数量を超過 ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "シリアル番号が見つかりません" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "固有のシリアル番号の数({n})は数量({q})と一致する必要があります。" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "この値からHTMLタグを削除" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "データに禁止されているマークダウン・コンテンツが含まれています。" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "接続エラー" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "サーバは無効なステータスコードで応答しました" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "例外が発生しました" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "サーバーが無効なContent-Length値で応答しました" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "画像サイズが大きすぎます" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "画像のダウンロードが最大サイズを超えました" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "リモートサーバーが空のレスポンスを返しました" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "指定されたURLは有効な画像ファイルではありません" @@ -207,11 +216,11 @@ msgstr "指定されたURLは有効な画像ファイルではありません" msgid "Log in to the app" msgstr "アプリにログイン" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "メールアドレス" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "二要素認証を有効にする必要があります。" @@ -255,133 +264,108 @@ msgstr "参照は必須パターンに一致する必要があります。" msgid "Reference number is too large" msgstr "参照番号が大きすぎる" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "無効な選択です" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "お名前" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "説明" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "説明 (オプション)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "パス" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "同じ親に重複した名前は存在しません。" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "マークダウンメモ (オプション)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "バーコード情報" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "サードパーティ製バーコードデータ" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "バーコードハッシュ" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "バーコードデータのユニークなハッシュ" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "既存のバーコードが見つかりました" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "タスクの失敗" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "バックグラウンドワーカータスク'{f}'が{n}回試行した後に失敗しました" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "サーバーエラー" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "サーバーによってエラーが記録されました。" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "有効な数字でなければなりません" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "通貨" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "利用可能なオプションから通貨を選択してください" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "この項目は空欄にできません。" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "無効な値です。" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "遠隔画像" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "外部画像ファイルのURL" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "外部URLからの画像ダウンロードは許可されていません" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "リモートURLからの画像ダウンロードに失敗しました" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "無効なコンテンツタイプ形式です" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "コンテンツタイプが見つかりません" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "コンテンツタイプが必須のミックスインクラスと一致しません" @@ -537,11 +521,11 @@ msgstr "中国語 (簡体字)" msgid "Chinese (Traditional)" msgstr "中国語 (繁体字)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "アップデートが利用可能" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "InvenTreeの更新版が利用可能になりました" @@ -553,30 +537,30 @@ msgstr "無効な物理単位" msgid "Not a valid currency code" msgstr "有効な通貨コードではありません。" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "注文ステータス" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "親ビルド" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "バリアントを含む" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "バリアントを含む" msgid "Part" msgstr "パーツ" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "カテゴリ" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "祖先ビルド" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "担当" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "割り当て" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "作成前" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "の後に作成されました。" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "開始日あり" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "開始日 前" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "開始日 後" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "目標期日あり" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "目標期日" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "以降の目標日" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "完成前" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "終了後" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "最小日付" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "最大日付" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "ツリーを除く" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "削除するには、ビルドをキャンセルする必要があります。" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "消耗品" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "オプション" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "アセンブリ" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "追跡" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "テスト可能" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "受注残高" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "割り当てられた" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "消費されました" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "注文中" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "組立注文" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "場所" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "出力" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "出力ストックアイテムIDでフィルタリングします。未インストールビルドアイテムを検索するには「null」をご使用ください。" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "組立注文" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "アセンブリBOMが検証されていません" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "非アクティブな部品にビルドオーダーを作成できません。" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "ロックされていない部品にビルドオーダーを作成できません。" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "ビルドオーダーを外部委託できるのは、購入可能部品のみです" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "担当ユーザーまたはグループを指定する必要があります。" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "ビルドオーダー部品は変更できません" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "目標期日は開始日以降であること" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "ビルド・オーダー・リファレンス" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "ビルド・オーダー・リファレンス" msgid "Reference" msgstr "参照" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "建築の簡単な説明(任意)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "製造する部品の選択" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "セールス・オーダー・リファレンス" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "ソース・ロケーション" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "このビルドで在庫を取得する場所を選択します(任意の在庫場所から取得する場合は空白のままにしてください)。" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "外部ビルド" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "このビルドオーダーは外部委託されます。" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "目的地" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "完成したアイテムの保管場所を選択" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "数量" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "構築するストックアイテムの数" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "完成品" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "完了した在庫アイテムの数" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "組立状況" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "ビルドステータスコード" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "バッチコード" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "このビルド出力のバッチコード" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "作成日時" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "ビルド開始日" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "この注文の開始予定日" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "完成目標日" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "ビルド完了目標日。この日付を過ぎると、ビルドは期限切れになります。" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "完了日" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "完了者" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "発行者" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "このビルドオーダーを発行したユーザー" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "責任" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "このビルドオーダーを担当するユーザーまたはグループ" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "外部リンク" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "外部 サイト へのリンク" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "組立優先度" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "建設順序の優先順位" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "プロジェクトコード" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "プロジェクトコード" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "製造中の子ビルドがあるため、ビルドオーダーを完了できません" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "不完全な出力があるため、ビルドオーダーを完了できません" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "ビルドの割り当てを完了するタスクのオフロードに失敗しました。" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "ビルドオーダー{build}が完了しました" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "建設発注が完了しました" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "追跡可能な部品については、シリアル番号の提示が必要です。" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "ビルド出力が指定されていません" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "ビルド出力はすでに完了しています" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "ビルド出力がビルド順序と一致しません" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "数量はゼロより大きくなければなりません" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "数量が出力数量を上回ることはできません" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "ビルド出力は、必要なすべてのテストを通過していません" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "割り当てられた項目を含むビルド出力の一部のみを完了することはできません" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "ビルドオーダーラインアイテム" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "ビルドオブジェクト" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "数量" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "注文数量" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "消費された在庫の数量" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "ビルド項目は、ビルド出力を指定する必要があります。" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "選択された在庫品目が部品表に一致しません。" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "シリアル在庫の場合、数量は1でなければなりません。" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "割当数量({q})は在庫可能数量({a})を超えてはなりません。" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "在庫が過剰配分" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "在庫商品" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "ソース在庫品" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "建設に割り当てる在庫量" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "インストール" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "仕向け地在庫品" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "ビルドレベル" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "部品名" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "ビルド出力" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "ビルド出力が親ビルドと一致しません" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "出力部分が BuildOrder 部分と一致しません。" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "このビルド出力はすでに完了しています" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "このビルド出力は完全に割り当てられていません" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "ビルド出力の数量を入力" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "追跡可能な部品に必要な整数個数" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "部品表には追跡可能な部品が含まれるため、必要な数量は整数" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "シリアル番号" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "ビルド出力のためのシリアル番号の入力" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "ビルド出力のストック位置" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "シリアル番号の自動割り当て" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "シリアル番号が一致する必要なアイテムを自動的に割り当て" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "以下のシリアル番号は既に存在するか、無効です。" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "ビルド出力のリストを提供する必要があります。" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "スクラップされたアウトプットの在庫場所" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "廃棄割り当て" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "廃棄されたアウトプットに割り当てられた在庫の破棄" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "ビルドアウトプットを廃棄する理由" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "完成した建造物のアウトプットの場所" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "不完全割当の受入れ" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "在庫が完全に割り当てられていない場合は、出力を完了します。" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "割当在庫の消費" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "このビルドに割り当て済みのストックを消費します。" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "不完全な出力の削除" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "完了していないビルド出力を削除します。" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "不可" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "このビルド・オーダーで消費されるものとして受け入れます。" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "このビルドオーダーを完了する前に割り当てを解除します。" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "総合在庫" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "製造オーダーに割り当てられた余分な在庫品をどのように処理しますか?" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "一部の在庫品目は全体的に配分されています。" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "未割り当ての受け入れ" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "在庫アイテムがこのビルド・オーダーに完全に割り当てられていないことを受け入れます。" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "必要在庫の配分が完了していません" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "インコンプリートの受け入れ" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "必要な数のビルドアウトプットが完了していないことを受け入れます。" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "必要な構築数量が完了していません" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "ビルド・オーダーには未完成の子ビルド・オーダーがあります。" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "受注生産状態であること" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "ビルド・オーダーの出力が不完全" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "組立ライン" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "ビルド出力" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "ビルド出力は同じビルド" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "ビルドラインアイテム" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.partは、ビルドオーダーと同じパーツを指す必要があります。" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "在庫があること" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "使用可能数量({q})を超過" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "追跡部品の割り当てには、ビルド出力を指定する必要があります。" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "追跡されていない部品の割り当てでは、ビルド出力を指定できません。" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "割り当て項目の提供" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "部品を調達する在庫場所(任意の場所から調達する場合は空白にしてください。)" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "場所を除く" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "この選択された場所から在庫商品を除外" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "交換可能ストック" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "複数の拠点にある在庫品を交換可能" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "代替ストック" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "代替部品の割り当て" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "オプション" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "オプションのBOMアイテムをビルドオーダーに割り当てます。" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "自動割り当てタスクの開始に失敗しました" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "BOMリファレンス" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "BOMパーツID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "部品表 部品名" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "ビルド" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "サプライヤー" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "割当数量" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "ビルドリファレンス" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "部品分類名" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "追跡可能" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "継承" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "バリアントを許可" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "BOMアイテム" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "生産中" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "ビルド予定" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "外部在庫" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "在庫状況" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "利用可能な代替ストック" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "在庫状況" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "消費量が割り当て量を超過しています" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "在庫消費に関する任意の注記" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "ビルド項目は正しいビルドオーダーを指す必要があります" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "重複したビルド項目の割り当て" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "ビルドラインは正しいビルドオーダーを指す必要があります" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "重複したビルドラインの割り当て" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "少なくとも1つの項目または行を指示する必要があります" @@ -1495,43 +1479,47 @@ msgstr "保留中" msgid "Cancelled" msgstr "キャンセル済" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "完了" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "受注生産に必要な在庫" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "ビルドオーダー{build}には追加の在庫が必要となります" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "期限切れ注文" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "ビルドオーダー{bo}は現在期限切れです" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "リンク" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "ファイル" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "ユーザーにはこれらの添付ファイルを削除する権限がありません。" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "ユーザーにはこの添付ファイルを削除する権限がありません" @@ -1551,798 +1539,822 @@ msgstr "有効な通貨コードはありません" msgid "No plugin" msgstr "プラグインなし" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "プロジェクトコードラベル" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "更新しました" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "最終更新のタイムスタンプ" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "更新者:" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "このオブジェクトを最後に更新したユーザー" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "独自のプロジェクトコード" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "プロジェクトの説明" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "このプロジェクトを担当するユーザーまたはグループ" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "設定キー" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "設定値" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "選択された値は有効なオプションではありません。" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "値はブール値でなければなりません。" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "値は整数値でなければなりません。" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "値は有効な数値でなければなりません。" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "値がバリデーション・チェックに合格しない" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "キー文字列は一意でなければなりません。" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "ユーザー" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "価格破壊数量" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "価格" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "指定数量での単価" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "エンドポイント" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "このウェブフックを受信するエンドポイント" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "このウェブフックの名前" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "有効" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "このウェブフックはアクティブですか" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "トークン" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "アクセス用トークン" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "シークレット" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "HMACの共有秘密" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "メッセージ ID:" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "このメッセージの一意な識別子" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "ホスト" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "このメッセージを受信したホスト" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "ヘッダー" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "このメッセージのヘッダー" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "本文" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "メッセージ本文" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "このメッセージを受信したエンドポイント" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "作業内容" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "このメッセージに関する作業は終わったのですか?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "タイトル" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "リンク" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "公開済み" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "投稿者" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "概要" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "既読" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "このニュースは読まれましたか?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "画像ファイル" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "この画像の対象モデルタイプ" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "この画像の対象モデルID" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "カスタムユニット" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "単位記号は一意でなければなりません。" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "ユニット名は有効な識別子でなければなりません。" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "ユニット名" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "シンボル" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "オプションの単位記号" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "定義" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "ユニットの定義" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "添付ファイル" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "ファイルがありません" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "外部リンクが見つかりません。" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "モデルタイプ" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "画像の対象モデルタイプ" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "添付ファイルを選択" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "コメント:" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "添付コメント" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "アップロード日" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "ファイルがアップロードされた日付" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "ファイルサイズ" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "ファイルサイズ(バイト" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "添付ファイルに指定されたモデルタイプが無効です" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "カスタムステート" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "カスタムステート" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "リファレンス・ステータス・セット" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "このカスタム状態で拡張されたステータスセット" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "論理キー" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "ビジネスロジックでこのカスタムステートに等しいステート論理キー" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "値" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "モデルのデータベースに保存される数値" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "都道府県名" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "ラベル" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "フロントエンドに表示されるラベル" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "色" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "フロントエンドに表示される色" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "モデル" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "この状態が関連するモデル" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "モデルを選択する必要があります" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "キーを選択する必要があります。" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "論理キーを選択する必要があります。" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "キーは論理キーと異なる必要があります。" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "有効な参照ステータスクラスが提供されなければならない" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "キーは、参照ステータスの論理キーとは異なる必要があります。" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "論理キーは、参照ステータスの論理キーに含まれていなければなりません。" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "リファレンス・ステータスの名前とは異なっていなければならない。" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "セレクションリスト" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "セレクション・リスト" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "選択リストの名前" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "選択リストの説明" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "ロック中" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "この選択リストはロックされていますか?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "このセレクションリストは使えますか?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "ソースプラグイン" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "選択リストを提供するプラグイン" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "ソースストリング" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "このリストに使用されているソースを示すオプションの文字列" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "デフォルトエントリー" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "この選択リストのデフォルト項目" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "作成日" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "選択リストが作成された日時" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "最終更新" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "選択リストが最後に更新された日時" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "セレクションリスト入力" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "セレクションリスト" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "このエントリーが属する選択リスト" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "選択リストエントリーの値" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "選択リスト項目のラベル" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "選択リスト項目の説明" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "この選択リストはアクティブですか?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "パラメータテンプレート" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "パラメータテンプレート" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "チェックボックスのパラメータに単位を指定することはできません。" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "チェックボックスパラメータに選択肢を持たせることはできません。" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "選択肢はユニークでなければなりません" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "パラメータ・テンプレート名は一意でなければなりません。" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "このパラメータテンプレートにおける対象モデルタイプ" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "パラメータ名" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "単位" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "このパラメータの物理単位" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "パラメータの説明" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "チェックボックス" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "このパラメータはチェックボックスですか?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "選択肢" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "このパラメータの有効な選択肢(カンマ区切り)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "このパラメータの選択リスト" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "有効" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "このパラメータテンプレートは有効ですか?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "パラメータ" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "パラメータ" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "パラメータ値の選択が無効" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "パラメータに対して無効なモデルタイプが指定されています" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "モデルID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "このパラメータの対象となるモデルのID" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "テンプレート" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "パラメータテンプレート" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "データ" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "パラメータ値" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "備考" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "任意のメモ欄" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "バーコードスキャン" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "バーコードデータ" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "バーコードをスキャンしたユーザー" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "タイムスタンプ" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "バーコードスキャンの日時" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "バーコードを処理したURLエンドポイント" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "コンテキスト" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "バーコードスキャンのコンテキストデータ" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "返答" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "バーコードスキャンによるレスポンスデータ" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "結果" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "バーコードスキャンは成功しましたか?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "エラーが発生しました" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "メールメッセージ" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "メールメッセージ" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "発表されました" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "送信" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "失敗" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "配送済み" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "確認済み" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "インバウンド" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "アウトバウンド" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "返信なし" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "配送状況を記録" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "読み取りを記録" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "クリックを記録" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "グローバルID" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "このメッセージの識別子(外部システムから提供される場合があります)" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "スレッドID" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "このメッセージスレッドの識別子(外部システムから提供される場合があります)" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "スレッド" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "このメッセージに関連するスレッド" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "優先順位" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "メールのスレッド" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "メールのスレッド" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "キー" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "このスレッドの固有キー(スレッドを識別するために使用されます)" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "このスレッドの固有識別子" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "内部を開始しました" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "このスレッドは内部で開始されたものですか?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "スレッドが作成された日時" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "スレッドが最後に更新された日時" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "受領品目" @@ -2392,1235 +2404,1303 @@ msgstr "環境変数によって設定が上書きされるかどうかを示し msgid "Override" msgstr "上書き" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "走行中" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "保留タスク" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "スケジュールされたタスク" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "失敗したタスク" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "タスクID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ユニークなタスクID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "ロック" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "ロック時間" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "タスク名" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "関数" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "機能名" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "引数" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "タスク引数" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "キーワード論争" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "タスクキーワード引数" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "ファイル名" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "モデルタイプ" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "このモデルの添付ファイルを作成または編集する権限がありません。" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "ユーザーは、このモデルのパラメータを作成または編集する権限がありません。" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "選択リストがロックされています" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "グループなし" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "サイトのURLが設定によってロックされています" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "再起動が必要" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "サーバーの再起動を必要とする設定が変更されました。" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "保留中の移行" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "保留中のデータベース移行数" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "有効な警告コード" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "有効な警告コードの辞書" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "インスタンスID" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "このInvenTreeインスタンスの一意識別子" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "アナウンスID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "サーバーのインスタンスIDをサーバーステータス情報でアナウンス(認証なし)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "サーバーインスタンス名" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "サーバーインスタンスの文字列記述子" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "インスタンス名を使用" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "タイトルバーにインスタンス名を使用" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "about`を表示する制限" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "スーパーユーザーにのみ `about` モーダルを表示します。" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "会社名" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "社内社名" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "ベース URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "サーバーインスタンスのベースURL" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "デフォルトの通貨" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "価格計算のベース通貨を選択" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "対応通貨" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "対応通貨コード一覧" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "通貨の更新間隔" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "為替レートの更新頻度 (ゼロに設定すると無効になります)" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "日" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "通貨更新プラグイン" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "通貨更新プラグイン" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "URLからダウンロード" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "外部URLからの画像ダウンロードを許可する" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "ダウンロードサイズ制限" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "外部URL画像の最大サイズ" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "URLからのダウンロードに使用されるユーザーエージェント" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "外部URLから画像やファイルをダウンロードする際に使用するユーザーエージェントを上書きすることができます。" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "厳格なURLバリデーション" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "URL検証時にスキーマ指定を要求" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "更新チェック間隔" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "アップデートをチェックする頻度 (ゼロに設定すると無効になります)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "自動バックアップ" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "データベースとメディアファイルの自動バックアップ" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "自動バックアップ間隔" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "自動バックアップイベント間の日数を指定" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "タスク削除間隔" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "バックグラウンドタスクの結果は、指定した日数後に削除されます。" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "エラーログ削除間隔" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "エラーログは指定した日数後に削除されます。" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "通知削除間隔" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "ユーザー通知は指定された日数後に削除されます。" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "メール削除間隔" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "メールメッセージは、指定された日数が経過後に削除されます。" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "メールログの保護" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "メールログエントリの削除を防止します" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "バーコードサポート" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "ウェブインターフェイスでバーコードスキャナのサポートを有効にします。" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "店舗バーコード結果" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "バーコードスキャン結果をデータベースに保存" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "バーコードスキャン最大カウント" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "バーコードスキャン結果の最大保存数" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "バーコード入力遅延" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "バーコード入力処理遅延時間" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "バーコードウェブカメラサポート" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "ブラウザのウェブカメラでバーコードのスキャンが可能" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "バーコード表示データ" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "バーコードデータをテキストとしてブラウザに表示" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "バーコード生成プラグイン" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "内部バーコードデータ生成に使用するプラグイン" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "部品改訂" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "パートのリビジョンフィールドを有効にします。" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "アセンブリ改訂のみ" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "組立部品のみ修正可能" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "アセンブリからの削除を許可" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "アセンブリで使用されている部品の削除を許可します。" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN 正規表現" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "部分IPNにマッチする正規表現パターン" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "IPNの重複を許可" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "複数のパートが同じIPNを共有できるようにします。" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "IPNの編集を許可" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "部品編集中にIPN値の変更を許可" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "部品表データのコピー" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "部品複製時にBOMデータをデフォルトでコピー" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "部品パラメータデータのコピー" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "部品複製時にデフォルトでパラメータデータをコピー" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "コピー部品テストデータ" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "部品複製時にテストデータをデフォルトでコピー" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "カテゴリー・パラメーター・テンプレートのコピー" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "部品作成時のカテゴリー・パラメーター・テンプレートのコピー" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "パーツはデフォルトのテンプレートです" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "パーツはデフォルトで他のコンポーネントから組み立てることができます" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "コンポーネント" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "パーツはデフォルトでサブコンポーネントとして使用できます" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "購入可能" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "パーツはデフォルトで購入可能です" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "販売可能" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "パーツはデフォルトで販売可能です" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "パーツはデフォルトで追跡可能です" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "バーチャル" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "パーツはデフォルトでバーチャル" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "関連部品を表示" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "部品の関連部品を表示" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "初期在庫データ" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "新規部品追加時に初期在庫を作成可能" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "サプライヤー初期データ" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "新しい部品を追加する際に、最初のサプライヤーデータを作成できるようにします。" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "部品名表示形式" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "部品名の表示形式" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "パーツカテゴリー デフォルトアイコン" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "パートカテゴリのデフォルトアイコン(空はアイコンがないことを意味します)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "価格の最小桁数" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "価格データのレンダリング時に表示する最小小数点以下の桁数" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "価格の小数点以下の桁数" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "価格データのレンダリング時に表示する小数点以下の桁数の最大値" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "サプライヤー価格の利用" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "全体的な価格計算にサプライヤーの価格破壊を含めること" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "購入履歴の上書き" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "過去の発注価格がサプライヤーの価格変動を上書き" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "ストックアイテム価格を使用" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "手動入力された在庫データから価格計算を行います。" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "在庫商品の価格設定年齢" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "この日数より古い在庫品を価格計算から除外します。" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "バリアント価格を使用" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "全体的な価格計算にバリアント価格を含む" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "アクティブバリアントのみ" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "バリアント価格の計算には、アクティブなバリアントパーツのみを使用します。" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "自動更新の価格設定" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "内部データが変更された際に、部品価格を自動的に更新します。" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "価格の再構築間隔" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "部品価格が自動的に更新されるまでの日数" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "社内価格" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "部品の内部価格の有効化" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "内部価格オーバーライド" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "利用可能な場合、内部価格は価格帯の計算より優先されます。" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "ラベル印刷の有効化" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "ウェブインターフェースからラベル印刷を有効にします。" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "ラベル画像DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "ラベル印刷プラグインに供給する画像ファイルを生成する際のDPI解像度" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "レポートの有効化" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "レポートの作成" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "デバッグモード" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "デバッグモードでのレポート生成(HTML出力)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "ログレポートエラー" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "レポート生成時に発生するエラーのログ" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "ページサイズ" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "PDFレポートのデフォルトのページサイズ" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "パラメータ単位の強制" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "単位が指定されている場合、パラメータ値は指定された単位に一致する必要があります。" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "世界的にユニークな連載" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "在庫品のシリアル番号はグローバルに一意でなければなりません。" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "枯渇在庫の削除" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "ストックアイテムが枯渇した場合のデフォルトの動作を決定します。" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "バッチコードテンプレート" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "ストックアイテムのデフォルトバッチコード生成用テンプレート" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "有効期限" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "在庫期限切れ機能の有効化" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "期限切れ株式の売却" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "期限切れ株式の売却を許可" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "在庫切れ時間" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "在庫品が期限切れとみなされるまでの日数" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "賞味期限切れ在庫の処理" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "期限切れの在庫を使用した建物の建築を許可" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "株式所有権" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "ストックロケーションとアイテムの所有権管理" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "在庫場所 デフォルトアイコン" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "在庫場所のデフォルトアイコン(空はアイコンがないことを意味します。)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "インストール済みストックアイテムの表示" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "ストックテーブルにインストールされたストックアイテムを表示" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "アイテム取り付けの際はBOMをチェック" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "親部品のBOMには、インストールされたストックアイテムが存在する必要があります。" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "在庫切れの転送を許可" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "ビルド・オーダー参照パターン" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Build Order参照フィールドの生成に必要なパターン" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "アクティブパートが必要" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "非稼動部品の製造オーダー作成を防止" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "ロックされた部分を要求" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "ロックされていない部品の製造オーダー作成を防止" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "有効なBOMが必要" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "BOMが検証されない限り、製造オーダーが作成されないようにします。" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "クローズド・チャイルド・オーダー" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "すべてのチャイルドオーダーが終了するまで、ビルドオーダーの完了を防止します。" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "外部ビルドオーダー" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "外部ビルドオーダー機能の有効化" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "テストがパスするまでブロック" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "必要なテストがすべて合格するまで、ビルド出力が完了しないようにします。" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "返品注文の有効化" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "ユーザーインターフェイスで返品注文機能を有効にします。" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "リターンオーダー参照パターン" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "返品注文参照フィールドの生成に必要なパターン" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "完了した返品注文の編集" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "注文完了後の返品注文の編集が可能" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "販売注文参照パターン" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "販売注文参照フィールドの生成に必要なパターン" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "販売注文のデフォルト出荷" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "販売注文でデフォルト出荷を作成可能" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "完了した販売注文の編集" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "出荷または完了後の販売注文の編集を許可します。" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "出荷には確認が必要です" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "商品が確認されるまで、出荷の完了をお控えください。" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "出荷された注文を完了としてマーク" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "出荷済みと表示された販売注文は、「出荷済み」ステータスを回避して自動的に完了します。" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "発注書参照フィールドの生成に必要なパターン" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "完了した発注書の編集" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "出荷後または完了後の発注書の編集が可能" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "通貨の変換" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "在庫を受け取る際、商品価値を基準通貨に変換" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "自動発注" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "すべての品目を受領した時点で、発注書を完了として自動的にマーク" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "パスワード忘れ" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "ログインページでのパスワード忘れ防止機能の有効化" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "登録の有効化" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "ログインページでユーザーの自己登録を可能にします。" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSOの有効化" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "ログインページでSSOを有効化" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "SSO登録の有効化" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "ログインページでSSOによるユーザーの自己登録を可能にします。" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "SSOグループ同期の有効化" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "InvenTreeグループとIdPが提供するグループの同期を有効にします。" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSOグループキー" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "IdP が提供する groups claim 属性の名前。" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSOグループマップ" -#: common/setting/system.py:966 +#: 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 "SSOグループからローカルのInvenTreeグループへのマッピング。ローカル・グループが存在しない場合は、作成されます。" -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "SSO外のグループを削除" -#: common/setting/system.py:974 +#: 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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "メールアドレスは必須です" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "サインアップ時にメールの入力を要求" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "SSOユーザーの自動入力" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "SSOアカウントデータからユーザー詳細を自動入力" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "メール2回" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "サインアップの際、ユーザーに2度メールを尋ねます。" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "パスワード2回" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "サインアップ時にパスワードを2回要求" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "許可ドメイン" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "特定のドメイン(@で始まるカンマ区切り)へのサインアップを制限します。" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "登録時のグループ" -#: common/setting/system.py:1014 +#: 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." msgstr "新規ユーザ登録時に割り当てられるグループ。SSOグループ同期が有効な場合、このグループはIdPからグループを割り当てられない場合にのみ設定されます。" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "MFAの実施" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "ユーザーは多要素セキュリティを使用する必要があります。" -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "起動時にプラグインをチェック" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "起動時にすべてのプラグインがインストールされていることを確認 - コンテナ環境では有効にします。" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "プラグインのアップデートの確認" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "インストールされているプラグインのアップデートを定期的にチェックします。" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "URL統合の有効化" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "プラグインがURLルートを追加できるようにします" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "ナビゲーション統合の有効化" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "プラグインをナビゲーションに統合可能" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "アプリとの統合" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "プラグインを有効にしてアプリを追加" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "スケジュール統合の有効化" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "スケジュールタスクを実行するプラグインの有効化" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "イベント統合の有効化" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "プラグインが内部イベントに応答できるようにします。" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "インターフェース統合の有効化" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "プラグインがユーザー・インターフェースに統合できるようにします。" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "メール連携を有効にする" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "プラグインを有効にして、送信/受信メールを処理できるようにします" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "プロジェクトコードの有効化" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "プロジェクトを追跡するためのプロジェクトコードの有効化" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "過去の在庫数量および価値を記録する機能を有効にします" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "外部ロケーションを除く" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "自動引取期間" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "ユーザーのフルネームを表示" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "ユーザー名の代わりにフルネームを表示" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "ユーザープロファイルの表示" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "プロフィールページにユーザーのプロフィールを表示" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "テストステーションデータの有効化" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "テスト結果のテストステーションデータ収集の有効化" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "マシン ping を有効にする" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "登録されたマシンの状態を確認するため、定期的なpingタスクを有効にしてください" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "エラー・レポートの受信" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "システムエラーの通知を受信" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "最後の中古印刷機" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "ユーザーの最後に使用した印刷機を保存" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "全モデル" @@ -3965,365 +4061,369 @@ msgstr "パートはアクティブ" msgid "Manufacturer is Active" msgstr "メーカーはアクティブ" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "サプライヤーが活動中" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "内部はアクティブ" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "サプライヤーの活動" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "製造元" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "会社名" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "在庫あり" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "会社" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "会社概要" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "会社概要" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "ウェブサイト" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "会社ホームページURL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "電話番号" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "連絡先電話番号" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "連絡先メールアドレス" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "お問い合わせ" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "連絡先" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "外部企業情報へのリンク" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "この会社は活動していますか?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "お客様" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "この会社に商品を販売していますか?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "サプライヤー" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "この会社から商品を購入しますか?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "メーカーは" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "この会社は部品を製造しているのですか?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "この会社で使用されるデフォルト通貨" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "納税者番号" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "法人税番号" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "住所" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "マイアカウント" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "会社を選択" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "住所" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "アドレスエントリを説明するタイトル" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "主な住所" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "プライマリアドレスに設定" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "1行目" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "丁目、番地、号など" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "2行目" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "建物名、部屋番号など" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "郵便番号" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "都市/地域" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "郵便番号 都市/地域" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "都道府県" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "都道府県" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "国" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "住所国" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "宅配便発送に関する注意事項" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "宅配便発送時の注意事項" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "社内出荷に関する注意事項" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "社内用出荷注意事項" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "住所情報へのリンク(外部)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "メーカー・パーツ" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "ベース部" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "部品を選択" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "メーカー選択" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "メーカー品番" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "外部メーカー部品リンク用URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "メーカー部品説明" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "パックユニットは、ベースユニットと互換性がある必要があります。" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "パック単位はゼロより大きくなければなりません。" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "リンクされたメーカー部品は、同じベース部品を参照する必要があります。" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "仕入先" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "サプライヤーを選択" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "サプライヤー在庫管理ユニット" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "このサプライヤーは活動していますか?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "メーカー部品の選択" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "外部サプライヤー部品リンク用URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "サプライヤーの部品説明" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "基本料金" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "ミニマムチャージ(例:仕入れ手数料)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "パッケージング" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "部品梱包" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "パック数量" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "1パックに供給される総量。単品の場合は空のままにしてください。" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "複数" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "複数注文" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "サプライヤーから入手可能な数量" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "空席状況更新" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "アベイラビリティ・データの最終更新日" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "サプライヤーの価格破壊" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "このサプライヤーで使用されるデフォルト通貨" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "会社名" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "在庫あり" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "価格割り引き" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "データのエクスポート中にエラーが発生しました" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "レコードの既存データベース識別子" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "カラムはすでにデータベースのフィールドにマッピングされています。" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "フィールドはすでにデータ列にマッピングされています。" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "カラムマッピングは有効なインポートセッションにリンクされている必要があります。" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "カラムがデータファイルに存在しません。" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "対象モデルにフィールドが存在しない" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "選択されたフィールドは読み取り専用です。" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "インポートセッション" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "フィールド" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "列" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "行インデックス" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "元の行データ" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "エラー" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "有効" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "既存の記録を更新するにはIDが必要です。" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "指定のIDで該当する記録は見つかりませんでした" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "無効なID形式が指定されました" @@ -4588,7 +4688,7 @@ msgstr "各ラベルの印刷部数" msgid "Connected" msgstr "接続済み" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "不明" @@ -4692,7 +4792,7 @@ msgstr "プロパティーキー" msgid "Value of the property" msgstr "プロパティー値" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "グループ" @@ -4720,7 +4820,7 @@ msgstr "進行状況タイプの場合の最大値。type=progress の場合に msgid "Order Reference" msgstr "注文参照" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "並外れた" @@ -4728,7 +4828,7 @@ msgstr "並外れた" msgid "Has Project Code" msgstr "プロジェクトコード" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "作成者" @@ -4764,57 +4864,69 @@ msgstr "目標期日" msgid "Target Date After" msgstr "以降の目標日" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "価格" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "完成前" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "終了後" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "外部ビルドオーダー" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "注文" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "注文完了" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "内部パーツ" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "注文保留" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "完了" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "出荷あり" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "注文" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "注文" msgid "Sales Order" msgstr "セールスオーダー" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "合計金額" msgid "Total price for this order" msgstr "この注文の合計金額" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "注文通貨" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "この注文の通貨(会社のデフォルトを使用する場合は空白のままにしてください。)" @@ -4851,718 +4963,750 @@ msgstr "この注文の通貨(会社のデフォルトを使用する場合は msgid "This order is locked and cannot be modified" msgstr "この注文はロックされており、変更できません。" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "連絡先が選択した会社と一致しません" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "開始日は目標期日より前でなければなりません。" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "指定の会社と住所が一致しません" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "ご注文内容(任意)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "この注文のプロジェクトコードを選択してください。" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "外部ページへのリンク" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "開始日" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "本注文の開始予定日" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "終了日に達したら" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "お届け予定日この期日を過ぎますと延滞となります。" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "発行日" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "オーダー発行日" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "この注文を担当するユーザーまたはグループ" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "本注文に関する連絡先" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "本注文の会社住所" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "注文参照" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "ステータス" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "発注状況" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "注文元の会社" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "サプライヤー・リファレンス" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "サプライヤー注文参照コード" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "受信" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "注文完了日" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "目的地" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "入荷商品のお届け先" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "部品サプライヤーは、POサプライヤーと一致する必要があります。" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "品目が発注書と一致しません" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "行項目にリンクされた部品が不足しています" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "数量は正の数でなければなりません。" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "顧客" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "販売先" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "販売注文状況" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "お客様リファレンス" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "顧客注文参照コード" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "出荷日" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "出荷元" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "注文はすでに完了しています。" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "注文はすでにキャンセルされました" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "未完了の注文にのみ完了マークを付けることができます。" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "出荷に不備があるため、注文を完了できません。" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "割り当てに不備があるため、注文を完了できません。" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "不完全な項目があるため、注文を完了できません。" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "注文はロックされ、変更できません。" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "品目数量" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "行項目参照" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "項目" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "この行項目の目標期日(注文の目標期日を使用する場合は空白のままにしてください。)" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "行項目の説明(オプション)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "この行の補足説明" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "単価" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "発注書項目" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "サプライヤーの部品はサプライヤーと一致しなければなりません。" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "ビルドオーダーは外部としてマークする必要があります" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "ビルドオーダーはアセンブリ部品にのみリンクできます" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "ビルドオーダーの部品は、ラインアイテムの部品と一致する必要があります。" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "受信" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "受領品目数" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "購入金額" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "購入単価" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "本品目により完成する外部ビルドオーダー" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "発注書追加行" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "販売注文明細" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "販売可能な部品のみを販売オーダーに割り当てることができます。" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "セール価格" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "販売単価" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "発送済み" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "出荷数量" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "販売注文の出荷" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "配送先住所はお客様と一致している必要があります" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "こちらの発送先住所" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "出荷日" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "配達日" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "貨物の引渡日" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "チェック済み" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "この貨物をチェックしたユーザー" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "発送" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "出荷番号" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "追跡番号" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "貨物追跡情報" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "請求書番号" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "関連する請求書の参照番号" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "発送済み" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "出荷品目に割り当てられた在庫がありません" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "出荷は完了前に必ず確認が必要となります" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "セールスオーダー追加ライン" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "販売注文の割り当て" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "在庫アイテムが割り当てられていません" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "在庫品を別部品のラインに割り当てることはできません。" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "部品のないラインに在庫を割り当てることはできません。" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "割当数量が在庫数量を超えることはできません" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "割当数量はゼロより大きくなければなりません" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "シリアル化された在庫品の場合、数量は1でなければなりません。" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "販売注文と出荷が一致しません" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "出荷が販売注文と一致しません" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "ライン" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "販売注文の出荷参照" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "アイテム" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "割り当てるストックアイテムを選択" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "在庫割当数量の入力" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "リターンオーダー参照" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "返品元の会社" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "返品状況" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "返品注文項目" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "在庫品の指定が必要です。" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "返品数量が在庫数量を超える場合" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "返品数量はゼロより大きくなければなりません。" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "シリアル化されたストックアイテムの数量が無効です。" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "お客様から返品する商品を選択" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "受領日" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "転帰" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "この項目の成果" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "この品目の返品または修理に関連する費用" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "リターンオーダー追加ライン" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "注文ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "複製する注文のID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "コピーライン" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "元の注文から行項目をコピー" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "余分な行をコピー" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "元の注文から余分な項目をコピー" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "ラインアイテム" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "完成路線" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "重複した注文" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "この注文を複製するためのオプションを指定します。" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "無効なオーダーID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "サプライヤー名" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "ご注文のキャンセルはできません。" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "未完了の行項目で注文を閉じることができます。" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "注文に不備がある場合" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "ご注文は受け付けておりません。" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "自動車価格" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "サプライヤーの部品データに基づいて購入価格を自動計算" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "購入価格通貨" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "アイテムのマージ" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "同じ品目、同じ仕向け地、同じ日付の品目を1つの品目に統合します。" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "内部部品番号" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "内部部品名" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "サプライヤー部品の指定が必要" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "注文書の指定が必要" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "サプライヤーは発注書と一致しなければなりません。" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "発注書はサプライヤーと一致している必要があります。" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "明細" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "受取商品の配送先選択" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "入荷在庫品のバッチコード入力" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "有効期限" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "入荷在庫の有効期限の入力" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "入荷した在庫品のシリアル番号の入力" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "入荷在庫品の包装情報の上書き" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "在庫品の入荷に関する注意事項" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "バーコード" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "スキャンされたバーコード" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "バーコードはすでに使用されています" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "項目は必ずご記入ください。" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "デスティネーション・ロケーションを指定する必要があります。" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "バーコードの値は一意でなければなりません。" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "発送" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "完了した出荷" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "販売価格通貨" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "割当項目" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "出荷の詳細は記載されていません" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "ラインアイテムは、この注文に関連付けられていません。" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "数量は正数でなければなりません。" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "割り当てるシリアル番号を入力" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "出荷済み" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "この注文には出荷が関連付けられていません" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "以下のシリアル番号に該当するものは見つかりませんでした。" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "以下のシリアル番号はご利用いただけません。" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "返品注文項目" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "ラインアイテムが返品オーダーと一致しません" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "ラインアイテムはすでに受領済み" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "商品の受け取りは、進行中の注文に対してのみ可能です。" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "返品数量" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "ライン価格通貨" @@ -5598,146 +5742,150 @@ msgstr "返金" msgid "Reject" msgstr "拒否" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "期限切れ発注書" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "発注書{po}は現在期限切れです" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "期限切れ販売注文" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "セールスオーダー{so}は現在期限切れです。" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "期限切れ返品注文" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "リターンオーダー{ro}は現在期限切れです" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "スター付き" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "星の数で絞り込む" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "深さ" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "カテゴリの深さでフィルタリング" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "最多メンバーレベル" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "トップレベルカテゴリーによるフィルタリング" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "カスケード表示" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "フィルタリング結果にサブカテゴリーを含めることができます。" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "親" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "親カテゴリーによる絞り込み" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "指定したカテゴリの下にあるサブカテゴリを除外します。" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "実績あり" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "バリエーション?" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "改訂版" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "改定あり" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "BOM有効" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "カスケードカテゴリ" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "もし該当する場合には、指定されたカテゴリの子カテゴリ内のアイテムを含めてください。" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "数値カテゴリIDまたはリテラル'null'でフィルタリングしてください" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "組み立て部分はテスト可能" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "コンポーネント部分はテスト可能" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "用途" @@ -5746,11 +5894,11 @@ msgstr "用途" msgid "Part Category" msgstr "パーツカテゴリ" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "パーツカテゴリ" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "デフォルトの場所" @@ -5778,7 +5926,7 @@ msgstr "このカテゴリの部品のデフォルトキーワード" msgid "Icon" msgstr "アイコン" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "アイコン (オプション)" @@ -5799,1025 +5947,1050 @@ msgstr "初期値" msgid "Default Parameter Value" msgstr "パラメータのデフォルト値" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "パーツ" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "ロックされた部品のパラメータは削除できません" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "ロックされた部品のパラメータを変更することはできません" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "この部分はロックされているため削除できません" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "このパートはまだアクティブなので削除できません。" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "この部品はアセンブリで使用されているため、削除できません。" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "パート'{self}'は'{parent}'(再帰的)のBOMでは使用できません。" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "パート'{parent}'は'{self}'のBOMで使用(再帰的)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPNは正規表現パターン{pattern}に一致しなければなりません。" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "パートはそれ自体の改訂にはなりえません" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "すでにリビジョンとなっている部分のリビジョンを作成することはできません。" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "リビジョンコードの指定が必要" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "修正が許されるのは組立部品のみ" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "テンプレート部品のリビジョンを作成できません" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "親部品は同じテンプレートを指す必要があります。" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "このシリアル番号の在庫品はすでに存在します" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "パート設定でIPNの重複が許可されていません。" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "重複する部品リビジョンが既に存在します。" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "この名前、IPN、リビジョンを持つ部品は既に存在します。" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "部品を構造部品のカテゴリーに割り当てることはできません!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "部品名" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "テンプレート" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "この部品はテンプレート部品ですか?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "この部品は他の部品の変形ですか?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "変種" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "部品の説明(オプション)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "キーワード" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "検索結果での視認性を向上させる部分キーワード" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "パーツカテゴリ" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" -msgstr "即時支払通知" +msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "部品のリビジョンまたはバージョン番号" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "リビジョン" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "この部品は他の部品の改訂版ですか?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "改訂版" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "この商品は通常どこに保管されていますか?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "デフォルトの有効期限" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "この部品の在庫品の有効期限(日単位" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "最小在庫" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "最低許容在庫量" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "この部品の単位" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "この部品は他の部品から作ることができますか?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "この部品を使って他の部品を作ることはできますか?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "このパーツはユニークなアイテムの追跡が可能ですか?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "この部品にテスト結果を記録することはできますか?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "この部品は外部のサプライヤーから購入できますか?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "この部品は顧客に販売できますか?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "この部分はアクティブですか?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "ロックされた部分は編集できません" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "これは、ソフトウェア製品やライセンスなどの仮想部品ですか?" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "部品表の検証が完了しました" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "こちらの部品の部品表(BOM)は有効でしょうか?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "BOMチェックサム" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "保存されたBOMのチェックサム" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOMチェック済み" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "BOMチェック日" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "作成ユーザー" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "この部分の責任者" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "複数販売" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "価格計算のキャッシュに使用される通貨" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "最小BOMコスト" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "構成部品の最低コスト" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "最大BOMコスト" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "構成部品の最大コスト" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "最低購入価格" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "過去の最低購入価額" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "最大購入費用" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "過去の最高購入価格" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "最低社内価格" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "社内価格ブレークに基づく最低コスト" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "社内最高価格" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "社内価格ブレークに基づく最大コスト" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "最低供給価格" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "外部サプライヤーからの部品の最低価格" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "サプライヤー最高価格" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "外部サプライヤーからの部品の最高価格" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "最小バリアントコスト" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "バリアントパーツの最小コストの計算" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "最大バリアントコスト" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "バリアント部品の最大コストの計算" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "最低料金" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "最低コストのオーバーライド" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "最大コスト" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "最大コストのオーバーライド" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "総合的な最小コストの計算" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "総合最大コストの計算" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "最低販売価格" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "価格破壊に基づく最低販売価格" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "最高販売価格" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "価格破壊に基づく最高販売価格" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "最低販売価格" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "過去の最低売却価格" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "最大販売価格" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "過去の最高売却価格" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "ストックテイク用部品" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "個数" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "棚卸時の個別在庫数" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "ストックテイク時の在庫可能量" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "日付" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "ストックテイク実施日" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "最低在庫コスト" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "手元在庫の最低見積原価" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "最大在庫コスト" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "手元在庫の最大見積原価" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "パーツセール価格" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "部品試験テンプレート" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "無効なテンプレート名 - 英数字を1文字以上含む必要があります。" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "テストテンプレートは、テスト可能な部分に対してのみ作成できます。" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "同じキーを持つテスト・テンプレートがパートに既に存在します。" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "試験名" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "テストの名前を入力します。" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "テストキー" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "テストの簡易キー" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "試験内容" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "このテストの説明を入力してください。" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "このテストは有効ですか?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "必須" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "このテストは合格するために必要ですか?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "価値が必要" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "このテストは、テスト結果を追加する際に値を必要としますか?" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "アタッチメントが必要" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "この試験では、試験結果を追加する際にファイルの添付が必要ですか。" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "このテストで有効な選択肢(カンマ区切り)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOMアイテムは変更できません - アセンブリがロックされています。" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM アイテムは変更できません - バリアントアセンブリがロックされています。" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "親部品を選択" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "サブパート" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "BOMで使用する部品を選択" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "このBOMアイテムのBOM数量" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "この部品表はオプションです。" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "このBOMアイテムは消耗品です。" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "設定数量" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "ビルドに必要な追加の必要量(セットアップ時の損失を考慮した分)" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "歩留まり損失" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "ビルドにおける推定歩留まり率(0~100%で表されます)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "丸め倍数" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "必要な生産数量を、この値の倍数に切り上げてください。" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "BOMアイテムリファレンス" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "BOMアイテムノート" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "チェックサムi" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "BOMラインのチェックサム" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "検証済み" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "このBOMアイテムは検証済みです" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "継承" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "この BOM アイテムは、バリアントパーツの BOM に継承されます。" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "このBOMアイテムには、バリアントパーツのストックアイテムを使用できます。" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "数量は追跡可能な部品の場合、整数値でなければなりません。" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "サブパーツの指定が必要" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "BOMアイテム代替" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "代用部品はマスター部品と同じにすることはできません。" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "親BOMアイテム" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "代用部品" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "パート #1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "パート #2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "関連部品を選択" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "この関係について" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "部品とそれ自身との間に部品関係を作ることはできません。" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "重複する関係が既に存在します。" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "親カテゴリ" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "親部品カテゴリー" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "サブカテゴリ" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "結果" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "このテンプレートに対して記録された結果の数" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "この在庫商品の購入通貨" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "ファイルが画像ではありません" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "オリジナルパート" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "複製する元の部品を選択" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "コピー画像" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "元の部分から画像をコピー" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "コピーBOM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "元の部品から部品表をコピー" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "コピーパラメータ" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "元の部品からパラメータデータをコピー" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "コピーノート" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "元のパートからメモをコピー" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "コピーテスト" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "元の部品からテスト用テンプレートをコピーしてください" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "初期在庫量" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "この部品の初期在庫数量を指定します。数量が0の場合、在庫は追加されません。" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "初期在庫場所" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "この部品の初期在庫場所を指定してください。" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "サプライヤーを選択してください。" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "メーカーを選択してください。" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "メーカー品番" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "選択された企業は有効なサプライヤーではありません。" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "選択された会社は有効な製造業者ではありません。" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "このMPNに一致するメーカー部品はすでに存在します。" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "このSKUに一致するサプライヤー部品は既に存在します。" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "カテゴリ名" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "建物" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "現在生産中の当該部品の数量" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "この部品の予定生産数量" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "在庫商品" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "リビジョン" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "総在庫" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "未割当株式" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "バリアントストック" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "重複部分" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "別のパートから初期データをコピー" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "初期在庫" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "初期在庫数で部品を作成" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "サプライヤー情報" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "この部品の初期サプライヤー情報を追加します。" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "コピーカテゴリパラメータ" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "選択したパーツカテゴリーからパラメータテンプレートをコピー" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "既存イメージ" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "既存の部品画像のファイル名" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "画像ファイルが存在しません" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "部品表全体の検証" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "ビルド" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "ビルドオーダーに必要なもの" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "ビルドオーダーに割り当てられました" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "セールスオーダーに必要なもの" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "セールスオーダーに割り当てられました" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "最小価格" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "最低価格の計算値の上書き" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "最低価格通貨" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "最大価格" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "最高価格の計算値を上書き" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "最高価格通貨" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "更新" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "この部品の価格を更新" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "提供された通貨から{default_currency}に変換できませんでした。" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "最低価格は最高価格を超えてはなりません。" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "最高価格は最低価格を下回ってはなりません。" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "親アセンブリを選択" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "構成部品の選択" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "BOMをコピーする部品を選択します。" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "既存データの削除" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "コピー前に既存のBOMアイテムを削除" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "インクルード継承" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "テンプレート化された部品から継承されたBOM項目を含めます。" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "無効な行をスキップ" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "無効な行をスキップするには、このオプションを有効にします。" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "コピー代用部品" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "BOMアイテムの重複時に代替部品をコピー" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "在庫不足通知" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "{part.name}の在庫が設定された最低レベルを下回りました。" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "在庫切れ通知" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "在庫品1点について、有効期限が近づいています。" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "在庫品のうち、{item_count}点の商品がまもなく期限切れとなります。" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "有効期限なし" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "期限切れ {abs(days_diff)} 日前" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "本日が期限となります" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} 日" @@ -7031,15 +7204,15 @@ msgstr "配分数量" msgid "Label printing failed" msgstr "ラベル印刷に失敗しました" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "ラベルをPDFにレンダリングする際のエラー" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "ラベルをHTMLにレンダリングする際のエラー" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "印刷する項目はありません" @@ -7100,7 +7273,7 @@ msgstr "バーコードのネイティブサポートを提供" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "部品変更通知" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "パーツ `{part.name}` が `{part_action}` イベントでトリガーされました。" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDFラベルプリンタ" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "PDFラベルの印刷をネイティブでサポート" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "デバッグモード" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "デバッグモードを有効にする - PDFの代わりに生のHTMLを返します。" @@ -7500,7 +7673,7 @@ msgstr "ボーダー" msgid "Print a border around each label" msgstr "各ラベルの周囲に枠線を印刷します。" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "ランドスケープ" @@ -7580,64 +7753,77 @@ msgstr "TMEバーコードのスキャンをサポートします。" msgid "The Supplier which acts as 'TME'" msgstr "「TME」として活動するサプライヤー" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "スタッフユーザーのみがプラグインを管理できます" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "プラグインのインストールが無効" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "プラグインのインストールに成功しました" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "{path} にプラグインをインストール" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "プラグインがレジストリに見つかりませんでした" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "プラグインはパッケージ化されていません" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "プラグインパッケージ名が見つかりません" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "スタッフユーザーのみがプラグインを管理できます" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "プラグインのアンインストールが無効" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "プラグインがアクティブなため、アンインストールできません。" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "このプラグインは必須のため、アンインストールすることはできません。" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "このプラグインはサンプルプラグインのため、アンインストールすることはできません。" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "プラグインは組み込みプラグインのため、アンインストールすることはできません。" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "プラグインがインストールされていません" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "プラグインのインストールが見つかりません" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "プラグインのアンインストールに成功" @@ -7689,21 +7875,21 @@ msgstr "パッケージプラグイン" msgid "Plugin" msgstr "プラグイン" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "著者は見つかりませんでした" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "プラグイン'{p}'は現在のInvenTreeバージョン{v}と互換性がありません。" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "プラグインには少なくともバージョン {v} が必要です。" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "プラグインに必要なバージョンは最大で{v}です。" @@ -7884,55 +8070,55 @@ msgstr "設置未確認" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "フルリロード" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "プラグインレジストリのフルリロードを実行します。" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "強制リロード" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "プラグイン・レジストリがすでにロードされていても、強制的に再ロードします。" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "プラグインの収集" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "プラグインの収集とレジストリへの追加" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "プラグインを有効化" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "このプラグインを有効化します" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "必須プラグインは無効化できません" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "設定の削除" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "データベースからプラグイン設定を削除します" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "この設定が適用されるユーザー" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "アイテム" @@ -7948,7 +8134,7 @@ msgstr "プラグインはラベル印刷をサポートしていません" msgid "Invalid label dimensions" msgstr "無効なラベル寸法" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "テンプレートに有効な項目がありません" @@ -7972,152 +8158,156 @@ msgstr "文字" msgid "Template file with this name already exists" msgstr "この名前のテンプレートファイルは既に存在します。" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "テンプレート名" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "テンプレート説明" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "リビジョン番号(自動インクリメント)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "プリントのモデルに装着" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "印刷時に、リンクされたモデルインスタンスに対してレポート出力を添付ファイルとして保存" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "ファイル名パターン" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "ファイル名生成パターン" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "テンプレートが有効" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "テンプレートの対象モデルタイプ" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "フィルター" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "テンプレートクエリフィルタ(key=valueペアのカンマ区切りリスト)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "テンプレートファイル" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "PDFレポートのページサイズ" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "レポートを横向きにレンダリング" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "統合" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "選択された項目に対して単一のレポートを生成します" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "テンプレート{self.name}から生成されたレポート" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "テンプレートの構文エラー" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "レポートの表示にエラーが発生しました" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "レポート生成エラー" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "レポート出力の統合エラー" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "幅 [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "ラベル幅(mm単位)" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "高さ [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "ラベルの高さ(mm単位)" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "ラベル印刷エラー" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "スニペット" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "レポートスニペットファイル" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "スニペットファイルの説明" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "資産" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "レポート資産ファイル" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "アセットファイルの説明" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "レポートテンプレートの選択" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "レポートに含める項目の主キーのリスト" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "ラベルテンプレートの選択" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "印刷プラグイン" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "ラベル印刷に使用するプラグインを選択します。" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "シリアル番号" @@ -8215,7 +8405,7 @@ msgstr "在庫品テストレポート" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "設置項目" @@ -8248,184 +8438,196 @@ msgstr "結果なし(必須)" msgid "No result" msgstr "何も結果はありません" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "アセットファイルが存在しません" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "画像ファイルが見つかりません" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image タグには Part インスタンスが必要です。" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image タグには Company インスタンスが必要です。" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "場所の深さによる絞り込み" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "トップレベルのロケーションによるフィルタリング" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "フィルタリング結果にサブロケーションを含めることができます。" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "親の位置" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "親の所在地でフィルタリング" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "部品名(大文字・小文字を区別しません)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "パート名に含まれるもの(大文字・小文字を区別しません)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "部品名(正規表現)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "パートIPN(大文字と小文字を区別しません)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "パートIPNに含まれるもの(大文字と小文字は区別されません)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "パートIPN(正規表現)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "最小在庫" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "最大在庫" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "ステータスコード" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "外部ロケーション" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "ビルド・オーダーで消費" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "その他在庫品に装着" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "パートツリー" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "更新前" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "更新後" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "ストックテイク前" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "ストックテイク後" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "有効期限" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "有効期限" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "期限失効" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "そのアイテムおよびそのすべての子孫を除外するためのStockItemのプライマリキーをご提供ください。" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "カスケードの所在地" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "もし真であれば、指定された場所の子要素に含まれる項目を含めます" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "数値のロケーションID、またはリテラル文字列の「null」でフィルタリングしてください。" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "数量が必要です" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "有効な部品を供給する必要があります。" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "指定されたサプライヤの部品が存在しません。" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "サプライヤー部品にはパックサイズが定義されていますが、use_pack_sizeフラグが設定されていません。" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "追跡不可能な部品については、シリアル番号は提供できません。" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "組み込み済みを含める" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "もし真であれば、指定した在庫アイテムの中に組み込まれている構成部品のテスト結果を含める" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "数値による在庫品IDでの絞り込み" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "ID {id} の在庫品は存在しません" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "ストックロケーションの種類" msgid "Default icon for all locations that have no icon set (optional)" msgstr "アイコンが設定されていないすべての場所のデフォルトアイコン (オプション)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "ストックロケーション" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "在庫場所" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "所有者を選択" @@ -8461,7 +8663,7 @@ msgstr "所有者を選択" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "外部" @@ -8481,274 +8683,282 @@ msgstr "このロケーションのロケーションタイプ" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "いくつかのストックアイテムがすでにストックロケーションに配置されているため、このストックロケーションを構造化することはできません!" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field}は存在しません" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "部品の指定が必要" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "在庫品は、構造的な在庫場所に配置することはできません!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "仮想部品にストックアイテムを作成できません" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "パートタイプ('{self.supplier_part.part}')は{self.part}でなければなりません。" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "シリアル番号のある商品は数量が1でなければなりません。" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "数量が1以上の場合、シリアル番号は設定できません。" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "アイテムはそれ自身に属することはできません" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "is_building=Trueの場合、アイテムはビルド・リファレンスを持っていなければならない。" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "ビルド参照が同じ部品オブジェクトを指していません。" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "親株式" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "ベース部" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "この在庫品に一致するサプライヤー部品を選択してください" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "この在庫品はどこにありますか?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "この在庫品は以下の梱包で保管されています。" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "設置場所" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "このアイテムは他のアイテムにインストールされていますか?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "この商品のシリアル番号" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "このストックアイテムのバッチコード" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "在庫数" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "ソースビルド" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "このストックアイテムのビルド" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "消費者" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "このストックアイテムを消費したビルドオーダー" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "発注元" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "この在庫商品の購入注文" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "販売先オーダー" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "在庫品の有効期限。この日を過ぎると在庫は期限切れとなります。" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "枯渇時に削除" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "在庫がなくなったら、このストックアイテムを削除します。" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "購入時の単品購入価格" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "パートに変換" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "数量が在庫数を超えています" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "部品が追跡可能に設定されていません" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "数量は整数でなければなりません。" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "数量は在庫数 ({self.quantity}) を超えてはなりません。" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "シリアル番号はリストとして提供されなければなりません" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "数量がシリアル番号と一致しません" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "構造上ロケーションに在庫を割り当てることはできません" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "テストテンプレートが存在しません" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "在庫商品が販売注文に割り当てられました" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "ストックアイテムが他のアイテムに装着されている場合" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "在庫商品には他の商品が含まれています。" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "在庫商品が顧客に割り当てられました" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "在庫品は現在生産中です。" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "連番在庫の統合はできません" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "在庫品の重複" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "在庫品目は同じ部品を参照してください。" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "在庫品は同じサプライヤーの部品を参照する必要があります。" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "在庫状況コードが一致していること" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "在庫がないため移動できません。" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "ストックアイテムのトラッキング" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "記入上の注意" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "在庫品テスト結果" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "このテストには値を指定する必要があります。" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "このテストには添付ファイルをアップロードする必要があります。" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "このテストでは無効な値です。" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "試験結果" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "テスト出力値" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "試験結果添付" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "テストノート" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "テストステーション" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "試験が実施された試験ステーションの識別子。" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "開始" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "テスト開始のタイムスタンプ" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "修了済み" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "テスト終了のタイムスタンプ" @@ -8792,246 +9002,246 @@ msgstr "シリアル番号を生成する部品を選択します。" msgid "Quantity of serial numbers to generate" msgstr "生成するシリアル番号の数" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "この結果のテストテンプレート" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "この部品に該当するテストが見つかりませんでした" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "テンプレートIDまたはテスト名が必要です。" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "試験終了時刻を試験開始時刻より早くすることはできません。" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "親アイテム" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "親株式" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "数量はパック数です。" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "パッケージサイズを使用" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "新しい商品のシリアル番号の入力" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "サプライヤー品番" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "期限切れ" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "子供用品" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "追跡項目" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "この在庫品の購入価格、単位またはパックあたり" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "シリアル化するストックアイテムの数を入力" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "在庫品目がしていされていません" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "数量は在庫数 ({q}) を超えてはなりません。" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "仕向け地" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "この部品にシリアル番号を割り当てることはできません" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "シリアル番号が既に存在します" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "インストールするストックアイテムを選択" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "設置数量" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "インストールするアイテムの数量を入力してください。" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "取引メモの追加(オプション)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "設置数量は1台以上" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "在庫がありません" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "選択した部品が部品表にない" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "設置する数量は、利用可能な数量を超えてはなりません。" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "アンインストール先の場所" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "在庫品を変換する部品を選択" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "選択された部分は、変換のための有効なオプションではありません。" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "SupplierPartが割り当てられている在庫品を変換できません。" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "在庫商品ステータスコード" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "ステータスを変更するストックアイテムを選択" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "ストックアイテムが選択されていません" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "サブロケーション" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "親株式所在地" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "パーツは販売可能でなければなりません" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "商品が販売オーダーに割り当てられています。" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "アイテムがビルドオーダーに割り当てられています。" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "在庫アイテムを割り当てるお客様" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "選択された企業は顧客ではありません" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "株式譲渡に関する注意事項" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "在庫品のリストが必要です。" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "株式併合に関する注意事項" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "不一致のサプライヤーを許可" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "異なるサプライヤの部品を持つ在庫品目をマージできるようにします。" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "不一致の状態を許可" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "異なるステータスコードを持つストックアイテムをマージすることができます。" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "少なくとも2つのストックアイテムを提供する必要があります。" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "変化なし" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "StockItem 主キー値" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "在庫がありません" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "在庫品目は既に在庫にあります" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "数量は負の数であってはなりません。" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "株式取引に関する注記" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "既存の在庫に統合します" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "可能なら、返品された商品を既存の在庫商品に統合してください" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "次のシリアル番号" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "以前のシリアル番号" @@ -9369,227 +9579,247 @@ msgstr "トークンが最後に使用された時間" msgid "Revoked" msgstr "失効" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "パーミッション設定" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "表示" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "項目を表示する権限" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "追加" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "項目を追加する権限" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "変更" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "項目を編集する権限" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "削除" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "項目を削除する権限" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "ボット" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "内部" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "ゲスト" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "言語" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "ユーザーの希望言語" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "テーマ" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "JSONとしてのウェブUI用の設定 - 手動で編集しないでください!" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "ウィジェット" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "JSONとしてのダッシュボード・ウィジェットの設定 - 手動で編集しないでください!" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "表示名" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "ユーザーの表示名選択" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "位置" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "主な役職名" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "ユーザーのステータスメッセージ" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "ユーザーの位置情報" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "ユーザーが積極的にシステムを利用" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "希望の連絡先" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "ユーザータイプ" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "どのようなユーザーですか?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "組織" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "ユーザーの主な所属組織" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "プライマリーグループ" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "ユーザーのプライマリグループ" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "管理者" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "購入注文" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "セールスオーダー" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "返品注文" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "ユーザー名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "ユーザーの名" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "姓" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "ユーザーの姓" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "ユーザーのメールアドレス" -#: users/serializers.py:309 -msgid "Staff" -msgstr "スタッフ" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "このユーザーにはスタッフ権限がありますか?" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "スーパーユーザー" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "このユーザーはスーパーユーザーですか?" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "このユーザーアカウントはアクティブですか" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "このフィールドを調整できるのはスーパーユーザーのみです。" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "パスワード" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "ユーザーのパスワード" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "警告を上書きします" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "パスワードルールに関する警告を無効にする" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "ユーザーを作成する権限がありません" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "アカウントが作成されました" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "パスワードリセット機能を使ってログインしてください" -#: users/serializers.py:452 +#: users/serializers.py:497 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 f34b545118..f7ea0862a1 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -19,45 +19,37 @@ msgstr "" #: InvenTree/api.py:365 msgid "API endpoint not found" -msgstr "" +msgstr "API 엔드포인트를 찾을 수 없습니다" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "일괄 작업을 위해 항목 목록을 제공해야 합니다" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" -msgstr "" +msgstr "항목은 목록 형태로 제공되어야 합니다" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" -msgstr "" +msgstr "잘못된 항목 목록이 제공되었습니다" + +#: InvenTree/api.py:458 +msgid "All filter must only be used with true" +msgstr "all 필터는 true와 함께만 사용할 수 있습니다" #: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 -msgid "All filter must only be used with true" -msgstr "" - -#: InvenTree/api.py:480 msgid "No items match the provided criteria" -msgstr "" +msgstr "제공된 조건과 일치하는 항목이 없습니다" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" -msgstr "" +msgstr "데이터가 제공되지 않았습니다" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." -msgstr "" +msgstr "이 필드는 고유해야 합니다." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "이 모델을 볼 수 있는 권한이 없습니다." @@ -71,38 +63,39 @@ msgstr "이메일 주소 확인" #: InvenTree/auth_overrides.py:85 msgid "You must type the same email each time." -msgstr "" +msgstr "매번 동일한 이메일을 입력해야 합니다." #: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 msgid "The provided primary email address is not valid." -msgstr "" +msgstr "제공된 기본 이메일 주소가 유효하지 않습니다." #: InvenTree/auth_overrides.py:145 msgid "The provided email domain is not approved." -msgstr "" +msgstr "제공된 이메일 도메인이 승인되지 않았습니다." #: InvenTree/conversion.py:240 #, python-brace-format msgid "Invalid unit provided ({unit})" -msgstr "" +msgstr "잘못된 단위가 제공되었습니다 ({unit})" #: InvenTree/conversion.py:257 msgid "No value provided" -msgstr "" +msgstr "값이 제공되지 않았습니다" #: InvenTree/conversion.py:284 #, python-brace-format msgid "Could not convert {original} to {unit}" -msgstr "" +msgstr "{original}을(를) {unit}(으)로 변환할 수 없습니다" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" -msgstr "" +msgstr "잘못된 수량이 제공되었습니다" #: InvenTree/exceptions.py:136 msgid "Error details can be found in the admin panel" -msgstr "" +msgstr "오류 상세 내용은 관리자 패널에서 확인할 수 있습니다" #: InvenTree/fields.py:146 msgid "Enter date" @@ -110,280 +103,271 @@ msgstr "날짜 입력" #: InvenTree/fields.py:169 msgid "Invalid decimal value" -msgstr "" +msgstr "잘못된 소수 값" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "메모" #: InvenTree/format.py:166 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" -msgstr "" +msgstr "값 '{name}'이(가) 패턴 형식에 없습니다" #: InvenTree/format.py:177 msgid "Provided value does not match required pattern: " -msgstr "" +msgstr "제공된 값이 요구되는 패턴과 일치하지 않습니다: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" -msgstr "" +msgstr "한 번에 1000개를 초과하여 직렬화할 수 없습니다" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" -msgstr "" +msgstr "시리얼 번호 문자열이 비어 있습니다" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" -msgstr "" +msgstr "중복된 시리얼" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" -msgstr "" +msgstr "잘못된 그룹: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" -msgstr "" +msgstr "그룹 범위 {group}이(가) 허용된 수량({expected_quantity})을 초과합니다" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" -msgstr "" +msgstr "시리얼 번호를 찾을 수 없습니다" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" -msgstr "" +msgstr "고유 시리얼 번호 개수({n})는 수량({q})과 일치해야 합니다" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" -msgstr "" +msgstr "이 값에서 HTML 태그를 제거하세요" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" -msgstr "" +msgstr "데이터에 금지된 마크다운 내용이 포함되어 있습니다" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "잘못된 URL: 호스트명이 없습니다" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "잘못된 URL: 호스트명을 확인할 수 없습니다" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "URL이 사설 또는 예약된 IP 주소를 가리킵니다" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "리디렉션이 너무 많습니다" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "연결 오류" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" -msgstr "" +msgstr "서버가 잘못된 상태 코드를 반환했습니다" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" -msgstr "" +msgstr "예외가 발생했습니다" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" -msgstr "" +msgstr "서버가 잘못된 Content-Length 값을 반환했습니다" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "이미지 크기가 너무 큽니다!" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" -msgstr "" +msgstr "이미지 다운로드가 최대 크기를 초과했습니다" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" -msgstr "" +msgstr "원격 서버가 빈 응답을 반환했습니다" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "이메일" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." -msgstr "" +msgstr "다른 작업을 하기 전에 먼저 2단계 인증을 활성화해야 합니다." #: InvenTree/models.py:114 msgid "Error running plugin validation" -msgstr "" +msgstr "플러그인 유효성 검사 실행 중 오류가 발생했습니다" #: InvenTree/models.py:195 msgid "Metadata must be a python dict object" -msgstr "" +msgstr "메타데이터는 파이썬 dict 객체여야 합니다" #: InvenTree/models.py:201 msgid "Plugin Metadata" -msgstr "" +msgstr "플러그인 메타데이터" #: InvenTree/models.py:202 msgid "JSON metadata field, for use by external plugins" -msgstr "" +msgstr "외부 플러그인에서 사용하는 JSON 메타데이터 필드" #: InvenTree/models.py:385 msgid "Improperly formatted pattern" -msgstr "" +msgstr "패턴 형식이 올바르지 않습니다" #: InvenTree/models.py:392 msgid "Unknown format key specified" -msgstr "" +msgstr "알 수 없는 형식 키가 지정되었습니다" #: InvenTree/models.py:398 msgid "Missing required format key" -msgstr "" +msgstr "필수 형식 키가 누락되었습니다" #: InvenTree/models.py:409 msgid "Reference field cannot be empty" -msgstr "" +msgstr "참조(Reference) 필드는 비워둘 수 없습니다" #: InvenTree/models.py:417 msgid "Reference must match required pattern" -msgstr "" +msgstr "참조(Reference)는 요구되는 패턴과 일치해야 합니다" #: InvenTree/models.py:448 msgid "Reference number is too large" -msgstr "" +msgstr "참조 번호가 너무 큽니다" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" -msgstr "" +msgstr "잘못된 선택입니다" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "이름" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "설명" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "설명 (선택 사항)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" -msgstr "" +msgstr "경로" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" -msgstr "" +msgstr "같은 상위 항목 아래에는 중복된 이름이 있을 수 없습니다" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" -msgstr "" +msgstr "마크다운 메모 (선택 사항)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "바코드 데이터" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" -msgstr "" +msgstr "서드파티 바코드 데이터" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" -msgstr "" +msgstr "바코드 해시" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" -msgstr "" +msgstr "바코드 데이터의 고유 해시" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" -msgstr "" +msgstr "기존 바코드를 찾았습니다" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "서버 오류" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." -msgstr "" +msgstr "서버에 오류가 기록되었습니다." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" -msgstr "" +msgstr "유효한 숫자여야 합니다" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" -msgstr "" +msgstr "통화" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" -msgstr "" +msgstr "사용 가능한 옵션에서 통화를 선택하세요" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." -msgstr "" +msgstr "이 필드는 null일 수 없습니다." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "유효하지 않은 값" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" -msgstr "" +msgstr "콘텐츠 타입 형식이 올바르지 않습니다" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" -msgstr "" +msgstr "콘텐츠 타입을 찾을 수 없습니다" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" -msgstr "" +msgstr "콘텐츠 타입이 필요한 믹스인 클래스와 일치하지 않습니다" #: InvenTree/setting/locales.py:20 msgid "Arabic" @@ -537,46 +521,46 @@ msgstr "중국어 (간체)" msgid "Chinese (Traditional)" msgstr "중국어 (번체)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" -msgstr "" +msgstr "업데이트 사용 가능" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" -msgstr "" +msgstr "InvenTree 업데이트가 있습니다" #: InvenTree/validators.py:28 msgid "Invalid physical unit" -msgstr "" +msgstr "잘못된 물리 단위" #: InvenTree/validators.py:34 msgid "Not a valid currency code" -msgstr "" +msgstr "유효한 통화 코드가 아닙니다" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" -msgstr "" +msgstr "주문 상태" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" -msgstr "" +msgstr "직상위 빌드" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" -msgstr "" +msgstr "변형(Variant) 포함" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,439 +569,443 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: 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:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "분류" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" -msgstr "" +msgstr "상위 계층 빌드" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "나에게 할당 됨" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" -msgstr "" +msgstr "할당 대상" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" -msgstr "" +msgstr "생성일 이전" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" -msgstr "" +msgstr "생성일 이후" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" -msgstr "" +msgstr "시작일 있음" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" -msgstr "" +msgstr "시작일 이전" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" -msgstr "" +msgstr "시작일 이후" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" -msgstr "" +msgstr "목표일 있음" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" -msgstr "" +msgstr "목표일 이전" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" -msgstr "" +msgstr "목표일 이후" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" -msgstr "" +msgstr "완료일 이전" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" -msgstr "" +msgstr "완료일 이후" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "최소 날짜" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "최대 날짜" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" -msgstr "" +msgstr "트리 제외" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" -msgstr "" +msgstr "빌드를 삭제하려면 먼저 취소해야 합니다" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "소모품" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "선택사항" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" -msgstr "" +msgstr "조립품" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" -msgstr "" +msgstr "추적됨" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" -msgstr "" +msgstr "테스트 가능" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" -msgstr "" +msgstr "미결 주문" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" -msgstr "" +msgstr "할당됨" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" -msgstr "" +msgstr "소모됨" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" -msgstr "" +msgstr "주문 중" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "빌드를 찾을 수 없습니다" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" -msgstr "" +msgstr "작업 지시서" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" -msgstr "" +msgstr "위치" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" -msgstr "" +msgstr "산출물" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." -msgstr "" +msgstr "산출물 재고 항목 ID로 필터링합니다. 설치되지 않은 빌드 항목을 찾으려면 'null'을 사용하세요." -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" -msgstr "" +msgstr "작업 지시서" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" -msgstr "" +msgstr "조립품 BOM이 검증되지 않았습니다" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" -msgstr "" +msgstr "비활성 부품에 대해서는 작업 지시서를 생성할 수 없습니다" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" -msgstr "" +msgstr "잠금 해제된 부품에 대해서는 작업 지시서를 생성할 수 없습니다" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" -msgstr "" +msgstr "외부 이행은 구매 가능한 부품에 대해서만 가능합니다" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" -msgstr "" +msgstr "담당 사용자 또는 그룹을 지정해야 합니다" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" -msgstr "" +msgstr "작업 지시서 부품은 변경할 수 없습니다" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" -msgstr "" +msgstr "목표일은 시작일 이후여야 합니다" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" -msgstr "" +msgstr "작업 지시서 참조번호" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 msgid "Reference" -msgstr "" +msgstr "참조" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" -msgstr "" +msgstr "빌드에 대한 간단한 설명 (선택 사항)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "이 빌드가 할당된 작업 지시서" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" -msgstr "" +msgstr "빌드할 부품을 선택하세요" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" -msgstr "" +msgstr "판매 주문 참조" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "이 빌드가 할당된 판매 주문" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" -msgstr "" +msgstr "원본 위치" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" -msgstr "" +msgstr "이 빌드에 사용할 재고를 가져올 위치를 선택하세요 (비워두면 어떤 재고 위치에서든 가져옵니다)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" -msgstr "" +msgstr "외주 생산" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" -msgstr "" +msgstr "이 작업 지시서는 외주로 생산됩니다" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" -msgstr "" +msgstr "대상 위치" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" -msgstr "" - -#: build/models.py:326 -msgid "Build Quantity" -msgstr "" +msgstr "완료된 항목이 보관될 위치를 선택하세요" #: build/models.py:329 +msgid "Build Quantity" +msgstr "빌드 수량" + +#: build/models.py:332 msgid "Number of stock items to build" -msgstr "" +msgstr "빌드할 재고 항목 수" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" -msgstr "" +msgstr "완료된 항목" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" -msgstr "" +msgstr "완료된 재고 항목 수" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" -msgstr "" +msgstr "빌드 상태" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" -msgstr "" +msgstr "빌드 상태 코드" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" -msgstr "" +msgstr "배치 코드" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" -msgstr "" +msgstr "이 빌드 산출물의 배치 코드" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" -msgstr "" +msgstr "생성일" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" -msgstr "" +msgstr "빌드 시작일" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" -msgstr "" +msgstr "이 작업 지시서의 예정 시작일" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" -msgstr "" +msgstr "목표 완료일" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." -msgstr "" +msgstr "빌드 완료 목표일. 이 날짜 이후에는 빌드가 지연으로 처리됩니다." -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" -msgstr "" +msgstr "완료일" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" -msgstr "" +msgstr "완료자" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" -msgstr "" +msgstr "발행자" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" -msgstr "" +msgstr "이 작업 지시서를 발행한 사용자" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" -msgstr "" +msgstr "담당" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" -msgstr "" +msgstr "이 작업 지시서를 담당하는 사용자 또는 그룹" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" -msgstr "" +msgstr "외부 링크" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" -msgstr "" +msgstr "외부 URL로 연결" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" -msgstr "" +msgstr "빌드 우선순위" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" -msgstr "" +msgstr "이 빌드 주문의 우선순위" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" -msgstr "" +msgstr "프로젝트 코드" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" -msgstr "" +msgstr "이 빌드 주문의 프로젝트 코드" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" -msgstr "" +msgstr "진행 중인 하위 빌드가 있는 상태에서는 작업 지시서를 완료할 수 없습니다" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" -msgstr "" +msgstr "미완료 산출물이 있는 상태에서는 작업 지시서를 완료할 수 없습니다" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" -msgstr "" +msgstr "빌드 자재 할당 완료 처리를 위한 작업 실행에 실패했습니다" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" -msgstr "" +msgstr "작업 지시서 {build}이(가) 완료되었습니다" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" -msgstr "" +msgstr "작업 지시서가 완료되었습니다" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" -msgstr "" +msgstr "추적 가능한 부품에는 시리얼 번호를 제공해야 합니다" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" -msgstr "" +msgstr "생산 완제품이 지정되지 않았습니다" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" -msgstr "" +msgstr "생산 완제품이 이미 완료되었습니다" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" -msgstr "" +msgstr "생산 완제품이 작업 지시서와 일치하지 않습니다" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" -msgstr "" +msgstr "수량은 0보다 커야 합니다" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" -msgstr "" +msgstr "수량은 산출물 수량보다 클 수 없습니다" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" -msgstr "" +msgstr "생산 완제품이 모든 필수 테스트를 통과하지 못했습니다" -#: build/models.py:1189 build/serializers.py:591 +#: build/models.py:1202 build/serializers.py:597 #, python-brace-format msgid "Build output {serial} has not passed all required tests" -msgstr "" +msgstr "생산 완제품 {serial}이(가) 모든 필수 테스트를 통과하지 못했습니다" -#: build/models.py:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "할당된 재고 항목이 아직 생산 중입니다" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" -msgstr "" +msgstr "할당된 항목이 있는 빌드 산출물은 부분 완료할 수 없습니다" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" -msgstr "" +msgstr "소요 자재 품목" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" -msgstr "" +msgstr "빌드 객체" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,6063 +1017,6248 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "수량" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" -msgstr "" +msgstr "작업 지시서에 필요한 수량" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" -msgstr "" +msgstr "소모된 재고 수량" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" -msgstr "" +msgstr "마스터 부품이 추적 가능으로 표시되어 있으므로, 빌드 항목은 생산 완제품을 지정해야 합니다" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" -msgstr "" +msgstr "선택한 재고 항목이 BOM 라인과 일치하지 않습니다" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "할당 수량은 0보다 커야 합니다" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" -msgstr "" +msgstr "시리얼이 있는 재고의 수량은 1이어야 합니다" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" -msgstr "" +msgstr "할당 수량({q})은 사용 가능한 재고 수량({a})을 초과할 수 없습니다" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" -msgstr "" +msgstr "재고 항목이 과다 할당되었습니다" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" -msgstr "" +msgstr "재고 항목" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" -msgstr "" +msgstr "원본 재고 항목" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" -msgstr "" +msgstr "빌드에 할당할 재고 수량" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" -msgstr "" +msgstr "설치 대상" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" -msgstr "" +msgstr "대상 재고 항목" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" -msgstr "" +msgstr "빌드 레벨" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" -msgstr "" +msgstr "부품명" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" -msgstr "" +msgstr "빌드 산출물" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" -msgstr "" +msgstr "빌드 산출물이 상위 빌드와 일치하지 않습니다" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" -msgstr "" +msgstr "산출물 부품이 빌드 주문 부품과 일치하지 않습니다" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" -msgstr "" +msgstr "이 빌드 산출물은 이미 완료되었습니다" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" -msgstr "" +msgstr "이 빌드 산출물은 완전히 할당되지 않았습니다" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" -msgstr "" - -#: build/serializers.py:333 -msgid "Integer quantity required for trackable parts" -msgstr "" +msgstr "빌드 산출물 수량을 입력하세요" #: build/serializers.py:339 -msgid "Integer quantity required, as the bill of materials contains trackable parts" -msgstr "" +msgid "Integer quantity required for trackable parts" +msgstr "추적 가능한 부품에는 정수 수량이 필요합니다" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:345 +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 msgid "Serial Numbers" msgstr "시리얼 번호 (일련번호)" -#: build/serializers.py:357 -msgid "Enter serial numbers for build outputs" -msgstr "" - #: build/serializers.py:363 +msgid "Enter serial numbers for build outputs" +msgstr "빌드 산출물의 시리얼 번호를 입력하세요" + +#: build/serializers.py:369 msgid "Stock location for build output" -msgstr "" +msgstr "빌드 산출물의 재고 위치" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" -msgstr "" +msgstr "시리얼 번호 자동 할당" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" -msgstr "" +msgstr "일치하는 시리얼 번호로 필요한 항목을 자동으로 할당합니다" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" -msgstr "" +msgstr "다음 시리얼 번호는 이미 존재하거나 유효하지 않습니다" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" -msgstr "" - -#: build/serializers.py:488 -msgid "Stock location for scrapped outputs" -msgstr "" +msgstr "빌드 산출물 목록을 제공해야 합니다" #: build/serializers.py:494 -msgid "Discard Allocations" -msgstr "" - -#: build/serializers.py:495 -msgid "Discard any stock allocations for scrapped outputs" -msgstr "" +msgid "Stock location for scrapped outputs" +msgstr "폐기된 산출물의 재고 위치" #: build/serializers.py:500 +msgid "Discard Allocations" +msgstr "할당 폐기" + +#: build/serializers.py:501 +msgid "Discard any stock allocations for scrapped outputs" +msgstr "폐기된 산출물에 대한 모든 재고 할당을 폐기합니다" + +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" -msgstr "" +msgstr "빌드 산출물 폐기 사유" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" -msgstr "" +msgstr "완료된 빌드 산출물의 위치" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" -msgstr "" +msgstr "불완전한 할당 허용" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" -msgstr "" +msgstr "재고가 완전히 할당되지 않았더라도 산출물을 완료합니다" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" -msgstr "" - -#: build/serializers.py:693 -msgid "Consume any stock which has already been allocated to this build" -msgstr "" +msgstr "할당된 재고 소모" #: build/serializers.py:699 +msgid "Consume any stock which has already been allocated to this build" +msgstr "이 빌드에 이미 할당된 모든 재고를 소모합니다" + +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" -msgstr "" +msgstr "미완료 산출물 제거" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" -msgstr "" +msgstr "완료되지 않은 모든 빌드 산출물을 삭제합니다" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" -msgstr "" +msgstr "허용되지 않음" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" -msgstr "" +msgstr "이 빌드 주문에 의해 소모된 것으로 수락" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" -msgstr "" +msgstr "이 빌드 주문을 완료하기 전에 할당을 해제하세요" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" -msgstr "" +msgstr "과다 할당된 재고" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" -msgstr "" +msgstr "빌드 주문에 추가로 할당된 재고 항목을 어떻게 처리하시겠습니까" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" -msgstr "" +msgstr "일부 재고 항목이 과다 할당되었습니다" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" -msgstr "" +msgstr "미할당 수락" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" -msgstr "" +msgstr "재고 항목이 이 빌드 주문에 완전히 할당되지 않았음을 수락합니다" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" -msgstr "" +msgstr "필요한 재고가 완전히 할당되지 않았습니다" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" -msgstr "" +msgstr "불완전 수락" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" -msgstr "" +msgstr "필요한 개수의 빌드 산출물이 완료되지 않았음을 수락합니다" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" -msgstr "" - -#: build/serializers.py:818 -msgid "Build order has open child build orders" -msgstr "" - -#: build/serializers.py:821 -msgid "Build order must be in production state" -msgstr "" +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 "" +msgstr "작업 지시서에 미완료 산출물이 있습니다" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" -msgstr "" +msgstr "빌드 라인" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" -msgstr "" +msgstr "생산 완제품" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" -msgstr "" +msgstr "생산 완제품은 동일한 빌드를 가리켜야 합니다" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" -msgstr "" +msgstr "빌드 라인 항목" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" -msgstr "" +msgstr "bom_item.part는 빌드 주문과 동일한 부품을 가리켜야 합니다" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" -msgstr "" +msgstr "항목은 재고에 있어야 합니다" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" -msgstr "" +msgstr "사용 가능한 수량({q})을 초과했습니다" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" -msgstr "" +msgstr "추적 부품을 할당하려면 생산 완제품을 지정해야 합니다" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" -msgstr "" +msgstr "비추적 부품 할당에는 생산 완제품을 지정할 수 없습니다" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" -msgstr "" +msgstr "할당 항목을 제공해야 합니다" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" -msgstr "" - -#: build/serializers.py:1098 -msgid "Exclude Location" -msgstr "" - -#: build/serializers.py:1099 -msgid "Exclude stock items from this selected location" -msgstr "" +msgstr "부품을 공급할 재고 위치 (비워두면 어떤 위치에서든 가져옵니다)" #: build/serializers.py:1104 -msgid "Interchangeable Stock" -msgstr "" +msgid "Exclude Location" +msgstr "위치 제외" #: build/serializers.py:1105 -msgid "Stock items in multiple locations can be used interchangeably" -msgstr "" +msgid "Exclude stock items from this selected location" +msgstr "선택한 위치의 재고 항목을 제외합니다" #: build/serializers.py:1110 -msgid "Substitute Stock" -msgstr "" +msgid "Interchangeable Stock" +msgstr "상호 대체 가능한 재고" #: build/serializers.py:1111 -msgid "Allow allocation of substitute parts" -msgstr "" +msgid "Stock items in multiple locations can be used interchangeably" +msgstr "여러 위치에 있는 재고 품목을 서로 대체하여 사용할 수 있습니다" #: build/serializers.py:1116 -msgid "Optional Items" -msgstr "" +msgid "Substitute Stock" +msgstr "대체 재고" #: build/serializers.py:1117 -msgid "Allocate optional BOM items to build order" -msgstr "" +msgid "Allow allocation of substitute parts" +msgstr "대체 부품 할당을 허용합니다" + +#: build/serializers.py:1122 +msgid "Optional Items" +msgstr "선택 항목" #: build/serializers.py:1123 +msgid "Allocate optional BOM items to build order" +msgstr "빌드 주문에 선택 BOM 항목을 할당합니다" + +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "모든 항목" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "비추적 항목" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "추적 항목" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "항목 유형" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "자동 할당할 항목 유형을 선택하세요" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" -msgstr "" +msgstr "BOM 참조" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" -msgstr "" +msgstr "BOM 부품 ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" -msgstr "" +msgstr "BOM 부품명" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "설치 대상" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" -msgstr "" +msgstr "빌드" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" -msgstr "" +msgstr "공급업체 부품" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" -msgstr "" +msgstr "할당 수량" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" -msgstr "" +msgstr "빌드 참조" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" -msgstr "" +msgstr "부품 카테고리 이름" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" -msgstr "" +msgstr "추적 가능" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" -msgstr "" +msgstr "상속됨" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" -msgstr "" +msgstr "변형(Variant) 허용" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" -msgstr "" +msgstr "BOM 항목" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" -msgstr "" +msgstr "생산 중" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" -msgstr "" +msgstr "빌드 예정" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" -msgstr "" +msgstr "외부 재고" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" -msgstr "" +msgstr "사용 가능 재고" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" -msgstr "" +msgstr "사용 가능 대체 재고" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" -msgstr "" +msgstr "사용 가능 변형(Variant) 재고" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" -msgstr "" +msgstr "소모 수량이 할당 수량을 초과합니다" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" -msgstr "" +msgstr "재고 소모에 대한 선택 메모" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" -msgstr "" +msgstr "빌드 항목은 올바른 빌드 주문을 가리켜야 합니다" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" -msgstr "" +msgstr "빌드 항목 할당이 중복되었습니다" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" -msgstr "" +msgstr "빌드 라인은 올바른 빌드 주문을 가리켜야 합니다" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" -msgstr "" +msgstr "빌드 라인 할당이 중복되었습니다" -#: build/serializers.py:1846 +#: build/serializers.py:1847 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 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 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 msgid "Cancelled" -msgstr "" +msgstr "취소됨" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" -msgstr "" +msgstr "완료" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" -msgstr "" +msgstr "빌드 주문에 재고가 필요합니다" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" -msgstr "" +msgstr "빌드 주문 {build}에 추가 재고가 필요합니다" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" -msgstr "" +msgstr "기한 초과 빌드 주문" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" -msgstr "" +msgstr "빌드 주문 {bo}이(가) 기한을 초과했습니다" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" -msgstr "" +msgstr "링크 여부" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" -msgstr "" +msgstr "파일 여부" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" +msgstr "사용자에게 이 첨부파일들을 삭제할 권한이 없습니다" + +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:779 +#: common/api.py:816 msgid "User does not have permission to delete this attachment" -msgstr "" +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:351 +#: common/filters.py:359 msgid "Project Code Label" -msgstr "" +msgstr "프로젝트 코드 라벨" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" -msgstr "" +msgstr "업데이트됨" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" -msgstr "" +msgstr "마지막 업데이트 타임스탬프" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" -msgstr "" +msgstr "업데이트 사용자" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" -msgstr "" +msgstr "이 객체를 마지막으로 업데이트한 사용자" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" -msgstr "" +msgstr "고유 프로젝트 코드" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" -msgstr "" +msgstr "프로젝트 설명" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" -msgstr "" +msgstr "이 프로젝트의 담당 사용자 또는 그룹" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" -msgstr "" +msgstr "설정 키" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" -msgstr "" +msgstr "설정 값" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" -msgstr "" +msgstr "선택한 값이 유효한 옵션이 아닙니다" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" -msgstr "" +msgstr "값은 불리언(Boolean)이어야 합니다" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" -msgstr "" +msgstr "값은 정수여야 합니다" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" -msgstr "" +msgstr "값은 유효한 숫자여야 합니다" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" -msgstr "" +msgstr "값이 유효성 검사 기준을 통과하지 못했습니다" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" -msgstr "" +msgstr "키 문자열은 고유해야 합니다" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" -msgstr "" +msgstr "사용자" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" -msgstr "" +msgstr "가격 구간 수량" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" -msgstr "" +msgstr "가격" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" -msgstr "" +msgstr "지정 수량에서의 단가" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" -msgstr "" +msgstr "엔드포인트" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" -msgstr "" +msgstr "이 웹훅을 수신하는 엔드포인트" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" -msgstr "" +msgstr "이 웹훅의 이름" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" -msgstr "" +msgstr "활성" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" -msgstr "" +msgstr "이 웹훅이 활성 상태인가요" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" -msgstr "" +msgstr "토큰" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" -msgstr "" +msgstr "접근용 토큰" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" -msgstr "" +msgstr "시크릿" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" -msgstr "" +msgstr "HMAC용 공유 시크릿" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" -msgstr "" +msgstr "메시지 ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" -msgstr "" +msgstr "이 메시지의 고유 식별자" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" -msgstr "" +msgstr "호스트" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" -msgstr "" +msgstr "이 메시지를 수신한 호스트" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" -msgstr "" +msgstr "헤더" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" -msgstr "" +msgstr "이 메시지의 헤더" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" -msgstr "" +msgstr "본문" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" -msgstr "" +msgstr "이 메시지의 본문" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" -msgstr "" +msgstr "이 메시지를 수신한 엔드포인트" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" -msgstr "" +msgstr "처리됨" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" -msgstr "" +msgstr "이 메시지 처리가 완료되었나요?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" -msgstr "" +msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" -msgstr "" +msgstr "제목" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" -msgstr "" +msgstr "링크" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" -msgstr "" +msgstr "게시됨" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" -msgstr "" +msgstr "작성자" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" -msgstr "" +msgstr "요약" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" -msgstr "" +msgstr "읽음" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" -msgstr "" - -#: common/models.py:1769 -msgid "Image file" -msgstr "" +msgstr "이 뉴스 항목을 읽었나요?" #: common/models.py:1781 +msgid "Image file" +msgstr "이미지 파일" + +#: common/models.py:1793 msgid "Target model type for this image" -msgstr "" +msgstr "이 이미지의 대상 모델 유형" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" -msgstr "" +msgstr "이 이미지의 대상 모델 ID" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" -msgstr "" +msgstr "사용자 정의 단위" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" -msgstr "" +msgstr "단위 기호는 고유해야 합니다" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" -msgstr "" +msgstr "단위 이름은 유효한 식별자여야 합니다" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" -msgstr "" +msgstr "단위 이름" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" -msgstr "" +msgstr "기호" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" -msgstr "" +msgstr "선택 단위 기호" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" -msgstr "" +msgstr "정의" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" -msgstr "" +msgstr "단위 정의" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" -msgstr "" +msgstr "첨부파일" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" -msgstr "" +msgstr "파일 누락" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" +msgstr "외부 링크 누락" + +#: common/models.py:2019 +msgid "No file attached to rename" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" -msgstr "" +msgstr "모델 유형" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" -msgstr "" +msgstr "이미지의 대상 모델 유형" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" -msgstr "" - -#: common/models.py:2014 -msgid "Comment" -msgstr "" - -#: common/models.py:2015 -msgid "Attachment comment" -msgstr "" - -#: common/models.py:2031 -msgid "Upload date" -msgstr "" - -#: common/models.py:2032 -msgid "Date the file was uploaded" -msgstr "" - -#: common/models.py:2036 -msgid "File size" -msgstr "" - -#: common/models.py:2036 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2074 common/serializers.py:715 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2095 -msgid "Custom State" -msgstr "" +msgstr "첨부할 파일을 선택하세요" #: common/models.py:2096 -msgid "Custom States" -msgstr "" +msgid "Comment" +msgstr "댓글" -#: common/models.py:2101 -msgid "Reference Status Set" -msgstr "" +#: common/models.py:2097 +msgid "Attachment comment" +msgstr "첨부파일 댓글" -#: common/models.py:2102 -msgid "Status set that is extended with this custom state" -msgstr "" - -#: common/models.py:2106 generic/states/serializers.py:18 -msgid "Logical Key" -msgstr "" - -#: common/models.py:2108 -msgid "State logical key that is equal to this custom state in business logic" -msgstr "" - -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 -msgid "Value" -msgstr "" +#: common/models.py:2113 +msgid "Upload date" +msgstr "업로드 날짜" #: common/models.py:2114 +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" +msgstr "사용자 정의 상태" + +#: common/models.py:2183 +msgid "Reference Status Set" +msgstr "참조 상태 세트" + +#: common/models.py:2184 +msgid "Status set that is extended with this custom state" +msgstr "이 사용자 정의 상태로 확장되는 상태 세트" + +#: common/models.py:2188 generic/states/serializers.py:18 +msgid "Logical Key" +msgstr "논리 키" + +#: common/models.py:2190 +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 +msgid "Value" +msgstr "값" + +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" -msgstr "" +msgstr "모델 데이터베이스에 저장될 숫자 값" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" -msgstr "" +msgstr "상태 이름" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" -msgstr "" +msgstr "라벨" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" -msgstr "" +msgstr "프론트엔드에 표시될 라벨" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" -msgstr "" +msgstr "색상" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" -msgstr "" +msgstr "프론트엔드에 표시될 색상" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" -msgstr "" +msgstr "모델" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" -msgstr "" +msgstr "이 상태가 연결된 모델" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" -msgstr "" +msgstr "모델을 선택해야 합니다" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" -msgstr "" +msgstr "키를 선택해야 합니다" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" -msgstr "" +msgstr "논리 키를 선택해야 합니다" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" -msgstr "" +msgstr "키는 논리 키와 달라야 합니다" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" -msgstr "" +msgstr "유효한 참조 상태 클래스가 제공되어야 합니다" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" -msgstr "" - -#: common/models.py:2192 -msgid "Logical key must be in the logical keys of the reference status" -msgstr "" - -#: common/models.py:2199 -msgid "Name must be different from the names of the reference status" -msgstr "" - -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 -msgid "Selection List" -msgstr "" - -#: common/models.py:2240 -msgid "Selection Lists" -msgstr "" - -#: common/models.py:2245 -msgid "Name of the selection list" -msgstr "" - -#: common/models.py:2252 -msgid "Description of the selection list" -msgstr "" - -#: common/models.py:2258 part/models.py:1293 -msgid "Locked" -msgstr "" - -#: common/models.py:2259 -msgid "Is this selection list locked?" -msgstr "" - -#: common/models.py:2265 -msgid "Can this selection list be used?" -msgstr "" - -#: common/models.py:2273 -msgid "Source Plugin" -msgstr "" +msgstr "키는 참조 상태의 논리 키들과 달라야 합니다" #: common/models.py:2274 -msgid "Plugin which provides the selection list" -msgstr "" +msgid "Logical key must be in the logical keys of the reference status" +msgstr "논리 키는 참조 상태의 논리 키 목록에 포함되어야 합니다" -#: common/models.py:2279 -msgid "Source String" -msgstr "" +#: common/models.py:2281 +msgid "Name must be different from the names of the reference status" +msgstr "이름은 참조 상태의 이름들과 달라야 합니다" -#: common/models.py:2280 -msgid "Optional string identifying the source used for this list" -msgstr "" +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +msgid "Selection List" +msgstr "선택 목록" -#: common/models.py:2289 -msgid "Default Entry" -msgstr "" +#: common/models.py:2322 +msgid "Selection Lists" +msgstr "선택 목록" -#: common/models.py:2290 -msgid "Default entry for this selection list" -msgstr "" +#: common/models.py:2327 +msgid "Name of the selection list" +msgstr "선택 목록 이름" -#: common/models.py:2295 common/models.py:3164 -msgid "Created" -msgstr "" +#: common/models.py:2334 +msgid "Description of the selection list" +msgstr "선택 목록 설명" -#: common/models.py:2296 -msgid "Date and time that the selection list was created" -msgstr "" +#: common/models.py:2340 part/models.py:1297 +msgid "Locked" +msgstr "잠김" -#: common/models.py:2301 -msgid "Last Updated" -msgstr "" - -#: common/models.py:2302 -msgid "Date and time that the selection list was last updated" -msgstr "" - -#: common/models.py:2336 -msgid "Selection List Entry" -msgstr "" - -#: common/models.py:2337 -msgid "Selection List Entries" -msgstr "" +#: common/models.py:2341 +msgid "Is this selection list locked?" +msgstr "이 선택 목록이 잠겨 있나요?" #: common/models.py:2347 -msgid "Selection list to which this entry belongs" -msgstr "" +msgid "Can this selection list be used?" +msgstr "이 선택 목록을 사용할 수 있나요?" -#: common/models.py:2353 -msgid "Value of the selection list entry" -msgstr "" +#: common/models.py:2355 +msgid "Source Plugin" +msgstr "소스 플러그인" -#: common/models.py:2359 -msgid "Label for the selection list entry" -msgstr "" +#: common/models.py:2356 +msgid "Plugin which provides the selection list" +msgstr "선택 목록을 제공하는 플러그인" -#: common/models.py:2365 -msgid "Description of the selection list entry" -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 "선택 목록 항목 설명" + +#: common/models.py:2482 msgid "Is this selection list entry active?" -msgstr "" +msgstr "이 선택 목록 항목이 활성 상태인가요?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" -msgstr "" +msgstr "매개변수 템플릿" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" -msgstr "" +msgstr "매개변수 템플릿" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" -msgstr "" - -#: common/models.py:2449 -msgid "Checkbox parameters cannot have choices" -msgstr "" - -#: common/models.py:2469 part/models.py:3672 -msgid "Choices must be unique" -msgstr "" - -#: common/models.py:2486 -msgid "Parameter template name must be unique" -msgstr "" - -#: common/models.py:2508 -msgid "Target model type for this parameter template" -msgstr "" - -#: common/models.py:2514 -msgid "Parameter Name" -msgstr "" - -#: common/models.py:2520 part/models.py:1246 -msgid "Units" -msgstr "" - -#: common/models.py:2521 -msgid "Physical units for this parameter" -msgstr "" - -#: common/models.py:2529 -msgid "Parameter description" -msgstr "" - -#: common/models.py:2535 -msgid "Checkbox" -msgstr "" - -#: common/models.py:2536 -msgid "Is this parameter a checkbox?" -msgstr "" - -#: common/models.py:2541 part/models.py:3759 -msgid "Choices" -msgstr "" - -#: common/models.py:2542 -msgid "Valid choices for this parameter (comma-separated)" -msgstr "" - -#: common/models.py:2553 -msgid "Selection list for this parameter" -msgstr "" - -#: common/models.py:2558 part/models.py:3734 report/models.py:287 -msgid "Enabled" -msgstr "" +msgstr "체크박스 매개변수에는 단위를 지정할 수 없습니다" #: common/models.py:2559 +msgid "Checkbox parameters cannot have choices" +msgstr "체크박스 매개변수에는 선택지를 지정할 수 없습니다" + +#: common/models.py:2579 part/models.py:3686 +msgid "Choices must be unique" +msgstr "선택지는 고유해야 합니다" + +#: common/models.py:2596 +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 "" +msgstr "이 매개변수 템플릿을 사용하나요?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" -msgstr "" +msgstr "매개변수" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" -msgstr "" +msgstr "매개변수" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" -msgstr "" +msgstr "매개변수 값에 대한 선택지가 올바르지 않습니다" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" -msgstr "" +msgstr "매개변수에 지정된 모델 유형이 올바르지 않습니다" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" -msgstr "" +msgstr "모델 ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" -msgstr "" +msgstr "이 매개변수의 대상 모델 ID" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" -msgstr "" +msgstr "템플릿" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" -msgstr "" +msgstr "매개변수 템플릿" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" -msgstr "" +msgstr "데이터" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" -msgstr "" +msgstr "매개변수 값" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" -msgstr "" +msgstr "메모" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" -msgstr "" +msgstr "선택적 메모 필드" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" -msgstr "" +msgstr "바코드 스캔" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" -msgstr "" +msgstr "바코드 데이터" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" -msgstr "" +msgstr "바코드를 스캔한 사용자" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" -msgstr "" +msgstr "타임스탬프" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" -msgstr "" +msgstr "바코드 스캔 날짜 및 시간" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" -msgstr "" +msgstr "바코드를 처리한 URL 엔드포인트" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" -msgstr "" +msgstr "컨텍스트" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" -msgstr "" +msgstr "바코드 스캔의 컨텍스트 데이터" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" -msgstr "" - -#: common/models.py:2851 -msgid "Response data from the barcode scan" -msgstr "" - -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 -msgid "Result" -msgstr "" - -#: common/models.py:2858 -msgid "Was the barcode scan successful?" -msgstr "" - -#: common/models.py:2940 -msgid "An error occurred" -msgstr "" +msgstr "응답" #: common/models.py:2961 +msgid "Response data from the barcode scan" +msgstr "바코드 스캔의 응답 데이터" + +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 +msgid "Result" +msgstr "결과" + +#: common/models.py:2968 +msgid "Was the barcode scan successful?" +msgstr "바코드 스캔이 성공했나요?" + +#: common/models.py:3050 +msgid "An error occurred" +msgstr "오류가 발생했습니다" + +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." -msgstr "" +msgstr "INVE-E8: 이메일 로그 삭제가 보호되어 있습니다. 삭제를 허용하려면 INVENTREE_PROTECT_EMAIL_LOG를 False로 설정하세요." -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" -msgstr "" +msgstr "이메일 메시지" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" -msgstr "" +msgstr "이메일 메시지" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" -msgstr "" +msgstr "공지됨" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" -msgstr "" +msgstr "전송됨" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" -msgstr "" +msgstr "실패" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" -msgstr "" +msgstr "전달됨" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" -msgstr "" +msgstr "확인됨" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" -msgstr "" +msgstr "수신" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" -msgstr "" - -#: common/models.py:3042 -msgid "No Reply" -msgstr "" - -#: common/models.py:3043 -msgid "Track Delivery" -msgstr "" - -#: common/models.py:3044 -msgid "Track Read" -msgstr "" - -#: common/models.py:3045 -msgid "Track Click" -msgstr "" - -#: common/models.py:3048 common/models.py:3151 -msgid "Global ID" -msgstr "" - -#: common/models.py:3061 -msgid "Identifier for this message (might be supplied by external system)" -msgstr "" - -#: common/models.py:3068 -msgid "Thread ID" -msgstr "" - -#: common/models.py:3070 -msgid "Identifier for this message thread (might be supplied by external system)" -msgstr "" - -#: common/models.py:3079 -msgid "Thread" -msgstr "" - -#: common/models.py:3080 -msgid "Linked thread for this message" -msgstr "" - -#: common/models.py:3096 -msgid "Priority" -msgstr "" - -#: common/models.py:3138 -msgid "Email Thread" -msgstr "" - -#: common/models.py:3139 -msgid "Email Threads" -msgstr "" - -#: common/models.py:3145 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 -msgid "Key" -msgstr "" - -#: common/models.py:3148 -msgid "Unique key for this thread (used to identify the thread)" -msgstr "" +msgstr "발신" #: common/models.py:3152 +msgid "No Reply" +msgstr "회신 없음" + +#: common/models.py:3153 +msgid "Track Delivery" +msgstr "전달 추적" + +#: common/models.py:3154 +msgid "Track Read" +msgstr "읽음 추적" + +#: common/models.py:3155 +msgid "Track Click" +msgstr "클릭 추적" + +#: common/models.py:3158 common/models.py:3261 +msgid "Global ID" +msgstr "전역 ID" + +#: common/models.py:3171 +msgid "Identifier for this message (might be supplied by external system)" +msgstr "이 메시지의 식별자(외부 시스템에서 제공될 수 있음)" + +#: common/models.py:3178 +msgid "Thread ID" +msgstr "스레드 ID" + +#: common/models.py:3180 +msgid "Identifier for this message thread (might be supplied by external system)" +msgstr "이 메시지 스레드의 식별자(외부 시스템에서 제공될 수 있음)" + +#: common/models.py:3189 +msgid "Thread" +msgstr "스레드" + +#: common/models.py:3190 +msgid "Linked thread for this message" +msgstr "이 메시지에 연결된 스레드" + +#: common/models.py:3206 +msgid "Priority" +msgstr "우선순위" + +#: common/models.py:3248 +msgid "Email Thread" +msgstr "이메일 스레드" + +#: common/models.py:3249 +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 +msgid "Key" +msgstr "키" + +#: common/models.py:3258 +msgid "Unique key for this thread (used to identify the thread)" +msgstr "이 스레드의 고유 키(스레드 식별에 사용)" + +#: common/models.py:3262 msgid "Unique identifier for this thread" -msgstr "" +msgstr "이 스레드의 고유 식별자" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" -msgstr "" +msgstr "내부 시작" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" -msgstr "" +msgstr "이 스레드는 내부에서 시작되었나요?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" -msgstr "" +msgstr "스레드가 생성된 날짜 및 시간" -#: common/models.py:3170 +#: common/models.py:3280 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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 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 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "이 설정 변경에 확인이 필요한지 여부를 나타냅니다" #: common/serializers.py:139 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" +msgstr "이 설정은 변경 전에 확인이 필요합니다. 변경을 확인해 주세요." #: common/serializers.py:172 msgid "Indicates if the setting is overridden by an environment variable" -msgstr "" +msgstr "이 설정이 환경 변수로 재정의되었는지 여부를 나타냅니다" #: common/serializers.py:174 msgid "Override" -msgstr "" +msgstr "재정의" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" -msgstr "" +msgstr "실행 중" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" -msgstr "" +msgstr "대기 중인 작업" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" -msgstr "" +msgstr "예약된 작업" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" -msgstr "" +msgstr "실패한 작업" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" -msgstr "" +msgstr "작업 ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" -msgstr "" +msgstr "고유 작업 ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" -msgstr "" +msgstr "잠금" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" -msgstr "" +msgstr "잠금 시간" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" -msgstr "" +msgstr "작업 이름" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" -msgstr "" +msgstr "함수" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" -msgstr "" +msgstr "함수 이름" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" -msgstr "" +msgstr "인수" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" -msgstr "" +msgstr "작업 인수" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" -msgstr "" +msgstr "키워드 인수" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" -msgstr "" +msgstr "작업 키워드 인수" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" -msgstr "" +msgstr "파일명" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" -msgstr "" +msgstr "모델 유형" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" -msgstr "" +msgstr "이 모델의 첨부파일을 생성하거나 편집할 권한이 없습니다" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" -msgstr "" +msgstr "이 모델의 매개변수를 생성하거나 편집할 권한이 없습니다" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" -msgstr "" +msgstr "선택 목록이 잠겨 있습니다" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" -msgstr "" +msgstr "그룹 없음" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" -msgstr "" - -#: common/setting/system.py:186 -msgid "Restart required" -msgstr "" +msgstr "사이트 URL이 구성에 의해 잠겨 있습니다" #: common/setting/system.py:187 -msgid "A setting has been changed which requires a server restart" -msgstr "" +msgid "Restart required" +msgstr "재시작 필요" -#: common/setting/system.py:193 -msgid "Pending migrations" -msgstr "" +#: common/setting/system.py:188 +msgid "A setting has been changed which requires a server restart" +msgstr "서버 재시작이 필요한 설정이 변경되었습니다" #: common/setting/system.py:194 -msgid "Number of pending database migrations" -msgstr "" +msgid "Pending migrations" +msgstr "대기 중인 마이그레이션" -#: common/setting/system.py:199 -msgid "Active warning codes" -msgstr "" +#: common/setting/system.py:195 +msgid "Number of pending database migrations" +msgstr "대기 중인 데이터베이스 마이그레이션 수" #: common/setting/system.py:200 -msgid "A dict of active warning codes" -msgstr "" +msgid "Active warning codes" +msgstr "활성 경고 코드" -#: common/setting/system.py:206 -msgid "Instance ID" -msgstr "" +#: common/setting/system.py:201 +msgid "A dict of active warning codes" +msgstr "활성 경고 코드의 딕셔너리" #: common/setting/system.py:207 +msgid "Instance ID" +msgstr "인스턴스 ID" + +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" -msgstr "" +msgstr "이 InvenTree 인스턴스의 고유 식별자" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" -msgstr "" +msgstr "ID 알림" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" -msgstr "" +msgstr "서버 상태 정보(인증 없음)에 서버 인스턴스 ID를 알립니다" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" -msgstr "" +msgstr "서버 인스턴스 이름" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" -msgstr "" - -#: common/setting/system.py:226 -msgid "Use instance name" -msgstr "" +msgstr "서버 인스턴스를 설명하는 문자열" #: common/setting/system.py:227 -msgid "Use the instance name in the title-bar" -msgstr "" +msgid "Use instance name" +msgstr "인스턴스 이름 사용" -#: common/setting/system.py:232 -msgid "Restrict showing `about`" -msgstr "" +#: common/setting/system.py:228 +msgid "Use the instance name in the title-bar" +msgstr "제목 표시줄에 인스턴스 이름을 사용합니다" #: common/setting/system.py:233 -msgid "Show the `about` modal only to superusers" -msgstr "" +msgid "Restrict showing `about`" +msgstr "`about` 표시 제한" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 -msgid "Company name" -msgstr "" +#: common/setting/system.py:234 +msgid "Show the `about` modal only to superusers" +msgstr "`about` 모달을 슈퍼유저에게만 표시합니다" #: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "슈퍼유저 배너 표시" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "슈퍼유저로 로그인했을 때 UI에 경고 배너를 표시합니다" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "관리자 배너 표시" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "관리자로 로그인했을 때 UI에 경고 배너를 표시합니다" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 +msgid "Company name" +msgstr "회사명" + +#: common/setting/system.py:252 msgid "Internal company name" -msgstr "" +msgstr "내부 회사명" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" -msgstr "" - -#: common/setting/system.py:244 -msgid "Base URL for server instance" -msgstr "" - -#: common/setting/system.py:250 -msgid "Default Currency" -msgstr "" - -#: common/setting/system.py:251 -msgid "Select base currency for pricing calculations" -msgstr "" +msgstr "기본 URL" #: common/setting/system.py:257 -msgid "Supported Currencies" -msgstr "" +msgid "Base URL for server instance" +msgstr "서버 인스턴스의 기본 URL" -#: common/setting/system.py:258 -msgid "List of supported currency codes" -msgstr "" +#: common/setting/system.py:263 +msgid "Default Currency" +msgstr "기본 통화" #: common/setting/system.py:264 -msgid "Currency Update Interval" -msgstr "" +msgid "Select base currency for pricing calculations" +msgstr "가격 계산에 사용할 기준 통화를 선택합니다" -#: common/setting/system.py:265 -msgid "How often to update exchange rates (set to zero to disable)" -msgstr "" - -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 -msgid "days" -msgstr "" +#: common/setting/system.py:270 +msgid "Supported Currencies" +msgstr "지원 통화" #: common/setting/system.py:271 -msgid "Currency Update Plugin" -msgstr "" - -#: common/setting/system.py:272 -msgid "Currency update plugin to use" -msgstr "" +msgid "List of supported currency codes" +msgstr "지원하는 통화 코드 목록" #: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" +msgid "Currency Update Interval" +msgstr "환율 업데이트 간격" #: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" +msgid "How often to update exchange rates (set to zero to disable)" +msgstr "환율을 업데이트하는 주기(0으로 설정하면 비활성화)" -#: common/setting/system.py:283 -msgid "Download Size Limit" -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 +msgid "days" +msgstr "일" #: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" +msgid "Currency Update Plugin" +msgstr "환율 업데이트 플러그인" + +#: common/setting/system.py:285 +msgid "Currency update plugin to use" +msgstr "사용할 환율 업데이트 플러그인" #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" +msgid "Strict URL Validation" +msgstr "엄격한 URL 검증" -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" +#: common/setting/system.py:291 +msgid "Require schema specification when validating URLs" +msgstr "URL 검증 시 스키마 지정을 요구합니다" + +#: common/setting/system.py:296 +msgid "Update Check Interval" +msgstr "업데이트 확인 간격" #: common/setting/system.py:297 -msgid "Strict URL Validation" -msgstr "" - -#: common/setting/system.py:298 -msgid "Require schema specification when validating URLs" -msgstr "" +msgid "How often to check for updates (set to zero to disable)" +msgstr "업데이트를 확인하는 주기(0으로 설정하면 비활성화)" #: common/setting/system.py:303 -msgid "Update Check Interval" -msgstr "" +msgid "Automatic Backup" +msgstr "자동 백업" #: common/setting/system.py:304 -msgid "How often to check for updates (set to zero to disable)" -msgstr "" +msgid "Enable automatic backup of database and media files" +msgstr "데이터베이스 및 미디어 파일의 자동 백업을 활성화합니다" + +#: common/setting/system.py:309 +msgid "Auto Backup Interval" +msgstr "자동 백업 간격" #: common/setting/system.py:310 -msgid "Automatic Backup" -msgstr "" - -#: common/setting/system.py:311 -msgid "Enable automatic backup of database and media files" -msgstr "" +msgid "Specify number of days between automated backup events" +msgstr "자동 백업 이벤트 사이의 일 수를 지정합니다" #: common/setting/system.py:316 -msgid "Auto Backup Interval" -msgstr "" - -#: common/setting/system.py:317 -msgid "Specify number of days between automated backup events" -msgstr "" - -#: common/setting/system.py:323 msgid "Task Deletion Interval" -msgstr "" +msgstr "작업 삭제 간격" + +#: common/setting/system.py:318 +msgid "Background task results will be deleted after specified number of days" +msgstr "백그라운드 작업 결과는 지정한 일 수 이후 삭제됩니다" #: common/setting/system.py:325 -msgid "Background task results will be deleted after specified number of days" -msgstr "" +msgid "Error Log Deletion Interval" +msgstr "오류 로그 삭제 간격" + +#: common/setting/system.py:326 +msgid "Error logs will be deleted after specified number of days" +msgstr "오류 로그는 지정한 일 수 이후 삭제됩니다" #: common/setting/system.py:332 -msgid "Error Log Deletion Interval" -msgstr "" - -#: common/setting/system.py:333 -msgid "Error logs will be deleted after specified number of days" -msgstr "" - -#: common/setting/system.py:339 msgid "Notification Deletion Interval" -msgstr "" +msgstr "알림 삭제 간격" + +#: common/setting/system.py:334 +msgid "User notifications will be deleted after specified number of days" +msgstr "사용자 알림은 지정한 일 수 이후 삭제됩니다" #: common/setting/system.py:341 -msgid "User notifications will be deleted after specified number of days" -msgstr "" - -#: common/setting/system.py:348 msgid "Email Deletion Interval" -msgstr "" +msgstr "이메일 삭제 간격" + +#: common/setting/system.py:343 +msgid "Email messages will be deleted after specified number of days" +msgstr "이메일 메시지는 지정한 일 수 이후 삭제됩니다" #: common/setting/system.py:350 -msgid "Email messages will be deleted after specified number of days" -msgstr "" +msgid "Protect Email Log" +msgstr "이메일 로그 보호" + +#: common/setting/system.py:351 +msgid "Prevent deletion of email log entries" +msgstr "이메일 로그 항목 삭제를 방지합니다" + +#: common/setting/system.py:356 +msgid "Barcode Support" +msgstr "바코드 지원" #: common/setting/system.py:357 -msgid "Protect Email Log" -msgstr "" +msgid "Enable barcode scanner support in the web interface" +msgstr "웹 인터페이스에서 바코드 스캐너 지원을 활성화합니다" -#: common/setting/system.py:358 -msgid "Prevent deletion of email log entries" -msgstr "" +#: common/setting/system.py:362 +msgid "Store Barcode Results" +msgstr "바코드 결과 저장" #: common/setting/system.py:363 -msgid "Barcode Support" -msgstr "" +msgid "Store barcode scan results in the database" +msgstr "바코드 스캔 결과를 데이터베이스에 저장합니다" -#: common/setting/system.py:364 -msgid "Enable barcode scanner support in the web interface" -msgstr "" +#: common/setting/system.py:368 +msgid "Barcode Scans Maximum Count" +msgstr "바코드 스캔 최대 개수" #: common/setting/system.py:369 -msgid "Store Barcode Results" -msgstr "" +msgid "Maximum number of barcode scan results to store" +msgstr "저장할 바코드 스캔 결과의 최대 개수" -#: common/setting/system.py:370 -msgid "Store barcode scan results in the database" -msgstr "" +#: common/setting/system.py:374 +msgid "Barcode Input Delay" +msgstr "바코드 입력 지연" #: common/setting/system.py:375 -msgid "Barcode Scans Maximum Count" -msgstr "" - -#: common/setting/system.py:376 -msgid "Maximum number of barcode scan results to store" -msgstr "" +msgid "Barcode input processing delay time" +msgstr "바코드 입력 처리 지연 시간" #: common/setting/system.py:381 -msgid "Barcode Input Delay" -msgstr "" +msgid "Barcode Webcam Support" +msgstr "바코드 웹캠 지원" #: common/setting/system.py:382 -msgid "Barcode input processing delay time" -msgstr "" +msgid "Allow barcode scanning via webcam in browser" +msgstr "브라우저에서 웹캠을 통한 바코드 스캔을 허용합니다" + +#: common/setting/system.py:387 +msgid "Barcode Show Data" +msgstr "바코드 데이터 표시" #: common/setting/system.py:388 -msgid "Barcode Webcam Support" -msgstr "" +msgid "Display barcode data in browser as text" +msgstr "브라우저에 바코드 데이터를 텍스트로 표시합니다" -#: common/setting/system.py:389 -msgid "Allow barcode scanning via webcam in browser" -msgstr "" +#: common/setting/system.py:393 +msgid "Barcode Generation Plugin" +msgstr "바코드 생성 플러그인" #: common/setting/system.py:394 -msgid "Barcode Show Data" -msgstr "" +msgid "Plugin to use for internal barcode data generation" +msgstr "내부 바코드 데이터 생성에 사용할 플러그인" -#: common/setting/system.py:395 -msgid "Display barcode data in browser as text" -msgstr "" +#: common/setting/system.py:399 +msgid "Part Revisions" +msgstr "부품 리비전" #: common/setting/system.py:400 -msgid "Barcode Generation Plugin" -msgstr "" +msgid "Enable revision field for Part" +msgstr "부품에 리비전 필드를 활성화합니다" -#: common/setting/system.py:401 -msgid "Plugin to use for internal barcode data generation" -msgstr "" +#: common/setting/system.py:405 +msgid "Assembly Revision Only" +msgstr "조립품 리비전만" #: common/setting/system.py:406 -msgid "Part Revisions" -msgstr "" +msgid "Only allow revisions for assembly parts" +msgstr "조립 부품에만 리비전을 허용합니다" -#: common/setting/system.py:407 -msgid "Enable revision field for Part" -msgstr "" +#: common/setting/system.py:411 +msgid "Allow Deletion from Assembly" +msgstr "조립품에서 삭제 허용" #: common/setting/system.py:412 -msgid "Assembly Revision Only" -msgstr "" +msgid "Allow deletion of parts which are used in an assembly" +msgstr "조립품에 사용되는 부품의 삭제를 허용합니다" -#: common/setting/system.py:413 -msgid "Only allow revisions for assembly parts" -msgstr "" +#: common/setting/system.py:417 +msgid "IPN Regex" +msgstr "IPN 정규식" #: common/setting/system.py:418 -msgid "Allow Deletion from Assembly" -msgstr "" - -#: common/setting/system.py:419 -msgid "Allow deletion of parts which are used in an assembly" -msgstr "" - -#: common/setting/system.py:424 -msgid "IPN Regex" -msgstr "" - -#: common/setting/system.py:425 msgid "Regular expression pattern for matching Part IPN" -msgstr "" +msgstr "부품 IPN과 일치시키기 위한 정규식 패턴" + +#: common/setting/system.py:421 +msgid "Allow Duplicate IPN" +msgstr "IPN 중복 허용" + +#: common/setting/system.py:422 +msgid "Allow multiple parts to share the same IPN" +msgstr "여러 부품이 동일한 IPN을 공유하도록 허용합니다" + +#: common/setting/system.py:427 +msgid "Allow Editing IPN" +msgstr "IPN 편집 허용" #: common/setting/system.py:428 -msgid "Allow Duplicate IPN" -msgstr "" +msgid "Allow changing the IPN value while editing a part" +msgstr "부품 편집 중 IPN 값 변경을 허용합니다" -#: common/setting/system.py:429 -msgid "Allow multiple parts to share the same IPN" -msgstr "" +#: common/setting/system.py:433 +msgid "Copy Part BOM Data" +msgstr "부품 BOM 데이터 복사" #: common/setting/system.py:434 -msgid "Allow Editing IPN" -msgstr "" +msgid "Copy BOM data by default when duplicating a part" +msgstr "부품을 복제할 때 기본으로 BOM 데이터를 복사합니다" -#: common/setting/system.py:435 -msgid "Allow changing the IPN value while editing a part" -msgstr "" +#: common/setting/system.py:439 +msgid "Copy Part Parameter Data" +msgstr "부품 매개변수 데이터 복사" #: common/setting/system.py:440 -msgid "Copy Part BOM Data" -msgstr "" +msgid "Copy parameter data by default when duplicating a part" +msgstr "부품을 복제할 때 기본으로 매개변수 데이터를 복사합니다" -#: common/setting/system.py:441 -msgid "Copy BOM data by default when duplicating a part" -msgstr "" +#: common/setting/system.py:445 +msgid "Copy Part Test Data" +msgstr "부품 테스트 데이터 복사" #: common/setting/system.py:446 -msgid "Copy Part Parameter Data" -msgstr "" +msgid "Copy test data by default when duplicating a part" +msgstr "부품을 복제할 때 기본으로 테스트 데이터를 복사합니다" -#: common/setting/system.py:447 -msgid "Copy parameter data by default when duplicating a part" -msgstr "" +#: common/setting/system.py:451 +msgid "Copy Category Parameter Templates" +msgstr "카테고리 매개변수 템플릿 복사" #: common/setting/system.py:452 -msgid "Copy Part Test Data" -msgstr "" - -#: common/setting/system.py:453 -msgid "Copy test data by default when duplicating a part" -msgstr "" +msgid "Copy category parameter templates when creating a part" +msgstr "부품을 생성할 때 카테고리 매개변수 템플릿을 복사합니다" #: common/setting/system.py:458 -msgid "Copy Category Parameter Templates" -msgstr "" - -#: common/setting/system.py:459 -msgid "Copy category parameter templates when creating a part" -msgstr "" - -#: common/setting/system.py:465 msgid "Parts are templates by default" -msgstr "" +msgstr "부품은 기본적으로 템플릿입니다" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" -msgstr "" +msgstr "부품은 기본적으로 다른 구성요소로 조립할 수 있습니다" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" -msgstr "" +msgstr "구성요소" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" -msgstr "" +msgstr "부품은 기본적으로 하위 구성요소로 사용할 수 있습니다" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" -msgstr "" +msgstr "구매 가능" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" -msgstr "" +msgstr "부품은 기본적으로 구매 가능합니다" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" -msgstr "" +msgstr "판매 가능" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" -msgstr "" +msgstr "부품은 기본적으로 판매 가능합니다" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" -msgstr "" +msgstr "부품은 기본적으로 추적 가능합니다" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" -msgstr "" +msgstr "가상" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" -msgstr "" +msgstr "부품은 기본적으로 가상입니다" + +#: common/setting/system.py:499 +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 "Show related parts" -msgstr "" +msgid "Allow creation of initial stock when adding a new part" +msgstr "새 부품 추가 시 초기 재고 생성을 허용합니다" -#: common/setting/system.py:507 -msgid "Display related parts for a part" -msgstr "" - -#: common/setting/system.py:512 -msgid "Initial Stock Data" -msgstr "" +#: common/setting/system.py:511 +msgid "Initial Supplier Data" +msgstr "초기 공급업체 데이터" #: common/setting/system.py:513 -msgid "Allow creation of initial stock when adding a new part" -msgstr "" +msgid "Allow creation of initial supplier data when adding a new part" +msgstr "새 부품 추가 시 초기 공급업체 데이터 생성을 허용합니다" -#: common/setting/system.py:518 -msgid "Initial Supplier Data" -msgstr "" +#: common/setting/system.py:519 +msgid "Part Name Display Format" +msgstr "부품명 표시 형식" #: common/setting/system.py:520 -msgid "Allow creation of initial supplier data when adding a new part" -msgstr "" +msgid "Format to display the part name" +msgstr "부품명을 표시하는 형식" #: common/setting/system.py:526 -msgid "Part Name Display Format" -msgstr "" +msgid "Part Category Default Icon" +msgstr "부품 카테고리 기본 아이콘" #: common/setting/system.py:527 -msgid "Format to display the part name" -msgstr "" +msgid "Part category default icon (empty means no icon)" +msgstr "부품 카테고리 기본 아이콘(비워두면 아이콘 없음)" -#: common/setting/system.py:533 -msgid "Part Category Default Icon" -msgstr "" +#: common/setting/system.py:532 +msgid "Minimum Pricing Decimal Places" +msgstr "가격 최소 소수 자릿수" #: common/setting/system.py:534 -msgid "Part category default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:539 -msgid "Minimum Pricing Decimal Places" -msgstr "" - -#: common/setting/system.py:541 msgid "Minimum number of decimal places to display when rendering pricing data" -msgstr "" +msgstr "가격 데이터를 표시할 때 최소 소수 자릿수" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" -msgstr "" +msgstr "가격 최대 소수 자릿수" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" -msgstr "" +msgstr "가격 데이터를 표시할 때 최대 소수 자릿수" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" -msgstr "" +msgstr "공급업체 가격 사용" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" -msgstr "" +msgstr "전체 가격 계산에 공급업체 수량별 가격을 포함합니다" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" -msgstr "" +msgstr "구매 이력 우선" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" -msgstr "" +msgstr "과거 구매 주문 가격이 공급업체 수량별 가격보다 우선합니다" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" -msgstr "" +msgstr "재고 항목 가격 사용" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" -msgstr "" +msgstr "가격 계산에 수동으로 입력한 재고 데이터의 가격을 사용합니다" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" -msgstr "" +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 "Exclude stock items older than this number of days from pricing calculations" -msgstr "" - -#: common/setting/system.py:598 msgid "Use Variant Pricing" -msgstr "" +msgstr "변형(Variant) 가격 사용" + +#: common/setting/system.py:592 +msgid "Include variant pricing in overall pricing calculations" +msgstr "전체 가격 계산에 변형(Variant) 가격을 포함합니다" + +#: common/setting/system.py:597 +msgid "Active Variants Only" +msgstr "활성 변형만" #: common/setting/system.py:599 -msgid "Include variant pricing in overall pricing calculations" -msgstr "" - -#: common/setting/system.py:604 -msgid "Active Variants Only" -msgstr "" - -#: common/setting/system.py:606 msgid "Only use active variant parts for calculating variant pricing" -msgstr "" +msgstr "변형(Variant) 가격 계산에 활성 변형 부품만 사용합니다" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" -msgstr "" +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 "Automatically update part pricing when internal data changes" -msgstr "" +msgid "Number of days before part pricing is automatically updated" +msgstr "부품 가격이 자동으로 업데이트되기까지의 일 수" #: common/setting/system.py:620 -msgid "Pricing Rebuild Interval" -msgstr "" +msgid "Internal Prices" +msgstr "내부 가격" #: common/setting/system.py:621 -msgid "Number of days before part pricing is automatically updated" -msgstr "" +msgid "Enable internal prices for parts" +msgstr "부품에 대해 내부 가격 사용" -#: common/setting/system.py:627 -msgid "Internal Prices" -msgstr "" +#: common/setting/system.py:626 +msgid "Internal Price Override" +msgstr "내부 가격 우선 적용" #: common/setting/system.py:628 -msgid "Enable internal prices for parts" -msgstr "" - -#: common/setting/system.py:633 -msgid "Internal Price Override" -msgstr "" - -#: common/setting/system.py:635 msgid "If available, internal prices override price range calculations" -msgstr "" +msgstr "가능한 경우 내부 가격이 가격 범위 계산보다 우선합니다" -#: common/setting/system.py:641 -msgid "Enable label printing" -msgstr "" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "BOM 수량 0 허용" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "라벨 인쇄 사용" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" -msgstr "" +msgstr "웹 인터페이스에서 라벨 인쇄를 사용합니다" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" -msgstr "" +msgstr "라벨 이미지 DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" -msgstr "" - -#: common/setting/system.py:655 -msgid "Enable Reports" -msgstr "" +msgstr "라벨 인쇄 플러그인에 제공할 이미지 파일 생성 시 DPI 해상도" #: common/setting/system.py:656 -msgid "Enable generation of reports" -msgstr "" +msgid "Enable Reports" +msgstr "보고서 사용" -#: common/setting/system.py:661 -msgid "Debug Mode" -msgstr "" +#: common/setting/system.py:657 +msgid "Enable generation of reports" +msgstr "보고서 생성을 사용합니다" #: common/setting/system.py:662 -msgid "Generate reports in debug mode (HTML output)" -msgstr "" +msgid "Debug Mode" +msgstr "디버그 모드" -#: common/setting/system.py:667 -msgid "Log Report Errors" -msgstr "" +#: common/setting/system.py:663 +msgid "Generate reports in debug mode (HTML output)" +msgstr "디버그 모드에서 보고서 생성(HTML 출력)" #: common/setting/system.py:668 +msgid "Log Report Errors" +msgstr "보고서 오류 로그" + +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" -msgstr "" +msgstr "보고서 생성 중 발생하는 오류를 기록합니다" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" -msgstr "" +msgstr "페이지 크기" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" -msgstr "" +msgstr "PDF 보고서의 기본 페이지 크기" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" -msgstr "" +msgstr "매개변수 단위 강제" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" -msgstr "" - -#: common/setting/system.py:687 -msgid "Globally Unique Serials" -msgstr "" +msgstr "단위가 제공된 경우, 매개변수 값은 지정된 단위와 일치해야 합니다" #: common/setting/system.py:688 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +msgid "Globally Unique Serials" +msgstr "전역 고유 시리얼" -#: common/setting/system.py:693 -msgid "Delete Depleted Stock" -msgstr "" +#: common/setting/system.py:689 +msgid "Serial numbers for stock items must be globally unique" +msgstr "재고 항목의 시리얼 번호는 전역적으로 고유해야 합니다" #: common/setting/system.py:694 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" +msgid "Delete Depleted Stock" +msgstr "소진된 재고 삭제" -#: common/setting/system.py:699 -msgid "Batch Code Template" -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" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 +msgid "Batch Code Template" +msgstr "배치 코드 템플릿" + +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" -msgstr "" +msgstr "재고 항목의 기본 배치 코드를 생성하기 위한 템플릿" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" -msgstr "" - -#: common/setting/system.py:705 -msgid "Enable stock expiry functionality" -msgstr "" - -#: common/setting/system.py:710 -msgid "Sell Expired Stock" -msgstr "" - -#: common/setting/system.py:711 -msgid "Allow sale of expired stock" -msgstr "" - -#: common/setting/system.py:716 -msgid "Stock Stale Time" -msgstr "" +msgstr "재고 만료" #: common/setting/system.py:718 -msgid "Number of days stock items are considered stale before expiring" -msgstr "" +msgid "Enable stock expiry functionality" +msgstr "재고 만료 기능 사용" -#: common/setting/system.py:725 -msgid "Build Expired Stock" -msgstr "" +#: common/setting/system.py:723 +msgid "Sell Expired Stock" +msgstr "만료 재고 판매" -#: common/setting/system.py:726 -msgid "Allow building with expired stock" -msgstr "" +#: common/setting/system.py:724 +msgid "Allow sale of expired stock" +msgstr "만료된 재고의 판매를 허용합니다" + +#: common/setting/system.py:729 +msgid "Stock Stale Time" +msgstr "재고 경과 시간" #: common/setting/system.py:731 -msgid "Stock Ownership Control" -msgstr "" - -#: common/setting/system.py:732 -msgid "Enable ownership control over stock locations and items" -msgstr "" - -#: common/setting/system.py:737 -msgid "Stock Location Default Icon" -msgstr "" +msgid "Number of days stock items are considered stale before expiring" +msgstr "만료 전 재고 항목을 오래된 것으로 간주하는 일 수" #: common/setting/system.py:738 -msgid "Stock location default icon (empty means no icon)" -msgstr "" +msgid "Build Expired Stock" +msgstr "만료 재고로 빌드" -#: common/setting/system.py:743 -msgid "Show Installed Stock Items" -msgstr "" +#: common/setting/system.py:739 +msgid "Allow building with expired stock" +msgstr "만료된 재고로 빌드하는 것을 허용합니다" #: common/setting/system.py:744 -msgid "Display installed stock items in stock tables" -msgstr "" +msgid "Stock Ownership Control" +msgstr "재고 소유권 제어" -#: common/setting/system.py:749 -msgid "Check BOM when installing items" -msgstr "" +#: common/setting/system.py:745 +msgid "Enable ownership control over stock locations and items" +msgstr "재고 위치 및 항목에 대한 소유권 제어를 사용합니다" + +#: common/setting/system.py:750 +msgid "Stock Location Default Icon" +msgstr "재고 위치 기본 아이콘" #: common/setting/system.py:751 -msgid "Installed stock items must exist in the BOM for the parent part" -msgstr "" +msgid "Stock location default icon (empty means no icon)" +msgstr "재고 위치 기본 아이콘(비어 있으면 아이콘 없음)" + +#: common/setting/system.py:756 +msgid "Show Installed Stock Items" +msgstr "설치된 재고 항목 표시" #: common/setting/system.py:757 +msgid "Display installed stock items in stock tables" +msgstr "재고 표에서 설치된 재고 항목을 표시합니다" + +#: common/setting/system.py:762 +msgid "Check BOM when installing items" +msgstr "항목 설치 시 BOM 확인" + +#: common/setting/system.py:764 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "설치된 재고 항목은 상위 부품의 BOM에 존재해야 합니다" + +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" -msgstr "" +msgstr "재고 없음 상태 이동 허용" -#: common/setting/system.py:759 +#: 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:765 -msgid "Build Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:766 -msgid "Required pattern for generating Build Order reference field" -msgstr "" - -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 -msgid "Require Responsible Owner" -msgstr "" - -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 -msgid "A responsible owner must be assigned to each order" -msgstr "" - -#: common/setting/system.py:777 -msgid "Require Active Part" -msgstr "" +msgstr "재고가 없는 재고 항목을 재고 위치 간에 이동할 수 있도록 허용합니다" #: common/setting/system.py:778 -msgid "Prevent build order creation for inactive parts" -msgstr "" +msgid "Build Order Reference Pattern" +msgstr "작업 지시서 참조번호 패턴" -#: common/setting/system.py:783 -msgid "Require Locked Part" -msgstr "" +#: common/setting/system.py:779 +msgid "Required pattern for generating Build Order reference field" +msgstr "작업 지시서 참조번호 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:784 -msgid "Prevent build order creation for unlocked parts" -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:789 -msgid "Require Valid BOM" -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 "Prevent build order creation unless BOM has been validated" -msgstr "" +msgid "Require Active Part" +msgstr "활성 부품 필수" -#: common/setting/system.py:795 -msgid "Require Closed Child Orders" -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 "잠긴 부품 필수" #: common/setting/system.py:797 -msgid "Prevent build order completion until all child orders are closed" -msgstr "" +msgid "Prevent build order creation for unlocked parts" +msgstr "잠기지 않은 부품에 대해 작업 지시서 생성을 방지합니다" + +#: common/setting/system.py:802 +msgid "Require Valid BOM" +msgstr "유효한 BOM 필수" #: common/setting/system.py:803 +msgid "Prevent build order creation unless BOM has been validated" +msgstr "BOM이 검증되지 않으면 작업 지시서 생성을 방지합니다" + +#: common/setting/system.py:808 +msgid "Require Closed Child Orders" +msgstr "하위 주문 종료 필수" + +#: common/setting/system.py:810 +msgid "Prevent build order completion until all child orders are closed" +msgstr "모든 하위 주문이 종료될 때까지 작업 지시서 완료를 방지합니다" + +#: common/setting/system.py:816 msgid "External Build Orders" -msgstr "" - -#: common/setting/system.py:804 -msgid "Enable external build order functionality" -msgstr "" - -#: common/setting/system.py:809 -msgid "Block Until Tests Pass" -msgstr "" - -#: common/setting/system.py:811 -msgid "Prevent build outputs from being completed until all required tests pass" -msgstr "" +msgstr "외주 생산 작업 지시서" #: common/setting/system.py:817 +msgid "Enable external build order functionality" +msgstr "외주 생산 작업 지시서 기능 사용" + +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 +msgid "Block Until Tests Pass" +msgstr "테스트 통과 전까지 차단" + +#: common/setting/system.py:832 +msgid "Prevent build outputs from being completed until all required tests pass" +msgstr "필수 테스트가 모두 통과될 때까지 생산 완제품 완료를 방지합니다" + +#: common/setting/system.py:838 msgid "Enable Return Orders" -msgstr "" - -#: common/setting/system.py:818 -msgid "Enable return order functionality in the user interface" -msgstr "" - -#: common/setting/system.py:823 -msgid "Return Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:825 -msgid "Required pattern for generating Return Order reference field" -msgstr "" - -#: common/setting/system.py:837 -msgid "Edit Completed Return Orders" -msgstr "" +msgstr "반품 주문 사용" #: common/setting/system.py:839 -msgid "Allow editing of return orders after they have been completed" -msgstr "" +msgid "Enable return order functionality in the user interface" +msgstr "사용자 인터페이스에서 반품 주문 기능을 사용합니다" -#: common/setting/system.py:845 -msgid "Sales Order Reference Pattern" -msgstr "" +#: common/setting/system.py:844 +msgid "Return Order Reference Pattern" +msgstr "반품 주문 참조 패턴" #: common/setting/system.py:846 -msgid "Required pattern for generating Sales Order reference field" -msgstr "" - -#: common/setting/system.py:857 -msgid "Sales Order Default Shipment" -msgstr "" +msgid "Required pattern for generating Return Order reference field" +msgstr "반품 주문 참조 필드를 생성하기 위한 필수 패턴" #: common/setting/system.py:858 -msgid "Enable creation of default shipment with sales orders" -msgstr "" +msgid "Edit Completed Return Orders" +msgstr "완료된 반품 주문 편집" -#: common/setting/system.py:863 -msgid "Edit Completed Sales Orders" -msgstr "" +#: common/setting/system.py:860 +msgid "Allow editing of return orders after they have been completed" +msgstr "반품 주문이 완료된 후에도 편집을 허용합니다" -#: common/setting/system.py:865 -msgid "Allow editing of sales orders after they have been shipped or completed" -msgstr "" +#: common/setting/system.py:866 +msgid "Sales Order Reference Pattern" +msgstr "판매 주문 참조 패턴" -#: common/setting/system.py:871 -msgid "Shipment Requires Checking" -msgstr "" +#: common/setting/system.py:867 +msgid "Required pattern for generating Sales Order reference field" +msgstr "판매 주문 참조 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:873 -msgid "Prevent completion of shipments until items have been checked" -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 "배송 확인 필요" + +#: common/setting/system.py:894 +msgid "Prevent completion of shipments until items have been checked" +msgstr "항목이 확인될 때까지 배송 완료를 방지합니다" + +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" -msgstr "" +msgstr "배송된 주문을 완료로 표시" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" -msgstr "" +msgstr "\"배송됨\" 상태를 건너뛰고, 배송된 것으로 표시된 판매 주문을 자동으로 완료 처리합니다" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" -msgstr "" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" +msgstr "구매 주문 참조 패턴" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" -msgstr "" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" +msgstr "구매 주문 참조 필드를 생성하기 위한 필수 패턴" #: common/setting/system.py:930 -msgid "Enable registration" -msgstr "" +msgid "Edit Completed Purchase Orders" +msgstr "완료된 구매 주문 편집" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" -msgstr "" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" +msgstr "구매 주문이 배송되었거나 완료된 후에도 편집을 허용합니다" -#: common/setting/system.py:936 -msgid "Enable SSO" -msgstr "" +#: common/setting/system.py:938 +msgid "Convert Currency" +msgstr "통화 변환" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" -msgstr "" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" +msgstr "재고 수령 시 항목 값을 기준 통화로 변환합니다" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" +msgid "Auto Complete Purchase Orders" +msgstr "구매 주문 자동 완료" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" -msgstr "" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" +msgstr "모든 라인 항목을 수령하면 구매 주문을 자동으로 완료로 표시합니다" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" +#: common/setting/system.py:953 +msgid "Enable password forgot" +msgstr "비밀번호 찾기 사용" -#: common/setting/system.py:958 -msgid "SSO group key" -msgstr "" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" +msgstr "로그인 페이지에서 비밀번호 찾기 기능을 사용합니다" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" +msgid "Enable registration" +msgstr "회원가입 사용" -#: common/setting/system.py:964 -msgid "SSO group map" -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 "SSO 사용" #: common/setting/system.py:966 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" +msgid "Enable SSO on the login pages" +msgstr "로그인 페이지에서 SSO를 사용합니다" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" -msgstr "" +#: common/setting/system.py:971 +msgid "Enable SSO registration" +msgstr "SSO 등록 사용" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "로그인 페이지에서 SSO를 통한 자기 등록(회원가입)을 사용합니다" -#: common/setting/system.py:980 -msgid "Email required" -msgstr "" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" +msgstr "SSO 그룹 동기화 사용" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" -msgstr "" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "IdP에서 제공하는 그룹과 InvenTree 그룹의 동기화를 사용합니다" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" -msgstr "" +msgid "SSO group key" +msgstr "SSO 그룹 키" -#: common/setting/system.py:992 -msgid "Mail twice" -msgstr "" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "IdP에서 제공하는 groups 클레임 속성의 이름" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" -msgstr "" +msgid "SSO group map" +msgstr "SSO 그룹 매핑" -#: common/setting/system.py:998 -msgid "Password twice" -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 "SSO 그룹을 로컬 InvenTree 그룹으로 매핑합니다. 로컬 그룹이 없으면 생성됩니다." -#: common/setting/system.py:999 -msgid "On signup ask users twice for their password" -msgstr "" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" +msgstr "SSO 외부 그룹 제거" -#: common/setting/system.py:1004 -msgid "Allowed domains" -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:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" -msgstr "" +#: common/setting/system.py:1009 +msgid "Email required" +msgstr "이메일 필수" -#: common/setting/system.py:1012 -msgid "Group on signup" -msgstr "" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" +msgstr "회원가입 시 이메일 입력을 요구합니다" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" +msgstr "SSO 사용자 자동 입력" -#: common/setting/system.py:1020 -msgid "Enforce MFA" -msgstr "" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" +msgstr "SSO 계정 데이터에서 사용자 상세 정보를 자동으로 채웁니다" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." -msgstr "" +msgid "Mail twice" +msgstr "이메일 2회 입력" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." -msgstr "" +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" +msgstr "회원가입 시 이메일을 두 번 입력하도록 요청합니다" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" -msgstr "" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "비밀번호 2회 입력" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" +msgstr "회원가입 시 비밀번호를 두 번 입력하도록 요청합니다" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" -msgstr "" +msgid "Allowed domains" +msgstr "허용된 도메인" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" -msgstr "" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" +msgstr "특정 도메인으로 회원가입을 제한합니다(쉼표로 구분, @로 시작)" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" -msgstr "" +msgid "Group on signup" +msgstr "회원가입 시 그룹" -#: common/setting/system.py:1047 -msgid "Enable URL integration" -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." +msgstr "등록 시 새 사용자가 할당될 그룹입니다. SSO 그룹 동기화가 활성화된 경우, IdP에서 그룹을 할당할 수 없을 때만 이 그룹이 설정됩니다." -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" -msgstr "" +#: common/setting/system.py:1049 +msgid "Enforce MFA" +msgstr "MFA 강제" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" -msgstr "" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." +msgstr "사용자는 다중 요소 보안을 사용해야 합니다." #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" -msgstr "" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +msgstr "이 설정을 활성화하면 모든 사용자가 다중 요소 인증을 설정해야 합니다. 모든 세션이 즉시 연결 해제됩니다." -#: common/setting/system.py:1061 -msgid "Enable app integration" -msgstr "" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" +msgstr "시작 시 플러그인 확인" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" -msgstr "" +msgid "Check that all plugins are installed on startup - enable in container environments" +msgstr "시작 시 모든 플러그인이 설치되어 있는지 확인합니다(컨테이너 환경에서 사용)" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" -msgstr "" +msgid "Check for plugin updates" +msgstr "플러그인 업데이트 확인" -#: common/setting/system.py:1075 -msgid "Enable event integration" -msgstr "" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" +msgstr "설치된 플러그인의 업데이트를 주기적으로 확인합니다" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" -msgstr "" +msgid "Enable URL integration" +msgstr "URL 통합 사용" -#: common/setting/system.py:1082 -msgid "Enable interface integration" -msgstr "" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" +msgstr "플러그인이 URL 라우트를 추가할 수 있도록 허용합니다" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" -msgstr "" +msgid "Enable navigation integration" +msgstr "내비게이션 통합 사용" -#: common/setting/system.py:1089 -msgid "Enable mail integration" -msgstr "" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" +msgstr "플러그인이 내비게이션에 통합될 수 있도록 허용합니다" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" -msgstr "" +msgid "Enable app integration" +msgstr "앱 통합 사용" -#: common/setting/system.py:1096 -msgid "Enable project codes" -msgstr "" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" +msgstr "플러그인이 앱을 추가할 수 있도록 허용합니다" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" -msgstr "" +msgid "Enable schedule integration" +msgstr "스케줄 통합 사용" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" -msgstr "" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" +msgstr "플러그인이 예약 작업을 실행할 수 있도록 허용합니다" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" -msgstr "" +msgid "Enable event integration" +msgstr "이벤트 통합 사용" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" -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 "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgid "Enable plugins to integrate into the user interface" +msgstr "플러그인이 사용자 인터페이스에 통합될 수 있도록 허용합니다" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" -msgstr "" +msgid "Enable mail integration" +msgstr "메일 통합 사용" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" -msgstr "" +msgid "Enable plugins to process outgoing/incoming mails" +msgstr "플러그인이 발신/수신 메일을 처리할 수 있도록 허용합니다" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" -msgstr "" +msgid "Enable project codes" +msgstr "프로젝트 코드 사용" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "과거 재고 수준과 가치를 기록하는 기능을 사용합니다" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "외부 위치 제외" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "외부 위치의 재고 품목을 재고 실사 계산에서 제외합니다" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "자동 재고 실사 주기" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "자동 재고 실사 기록 간격(일)" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "오래된 재고 실사 항목 삭제" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "지정된 일수보다 오래된 재고 실사 항목을 삭제합니다" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "재고 실사 삭제 간격" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" - -#: common/setting/system.py:1142 -msgid "Delete Old Stock Tracking Entries" -msgstr "" - -#: common/setting/system.py:1144 -msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" - -#: common/setting/system.py:1150 -msgid "Stock Tracking Deletion Interval" -msgstr "" - -#: common/setting/system.py:1152 -msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" - -#: common/setting/system.py:1159 -msgid "Display Users full names" -msgstr "" - -#: common/setting/system.py:1160 -msgid "Display Users full names instead of usernames" -msgstr "" - -#: common/setting/system.py:1165 -msgid "Display User Profiles" -msgstr "" - -#: common/setting/system.py:1166 -msgid "Display Users Profiles on their profile page" -msgstr "" +msgstr "재고 실사 항목은 지정된 일수 후 삭제됩니다" #: common/setting/system.py:1171 -msgid "Enable Test Station Data" -msgstr "" +msgid "Delete Old Stock Tracking Entries" +msgstr "오래된 재고 추적 항목 삭제" -#: common/setting/system.py:1172 -msgid "Enable test station data collection for test results" -msgstr "" - -#: common/setting/system.py:1177 -msgid "Enable Machine Ping" -msgstr "" +#: common/setting/system.py:1173 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "지정된 일수보다 오래된 재고 추적 항목을 삭제합니다" #: common/setting/system.py:1179 -msgid "Enable periodic ping task of registered machines to check their status" +msgid "Stock Tracking Deletion Interval" +msgstr "재고 추적 삭제 간격" + +#: common/setting/system.py:1181 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "재고 추적 항목은 지정된 일수 후 삭제됩니다" + +#: common/setting/system.py:1188 +msgid "Display Users full names" +msgstr "사용자 전체 이름 표시" + +#: common/setting/system.py:1189 +msgid "Display Users full names instead of usernames" +msgstr "사용자 이름 대신 사용자 전체 이름을 표시합니다" + +#: common/setting/system.py:1194 +msgid "Display User Profiles" +msgstr "사용자 프로필 표시" + +#: common/setting/system.py:1195 +msgid "Display Users Profiles on their profile page" +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" +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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 +msgid "Enable Test Station Data" +msgstr "테스트 스테이션 데이터 사용" + +#: common/setting/system.py:1215 +msgid "Enable test station data collection for test results" +msgstr "테스트 결과를 위한 테스트 스테이션 데이터 수집을 사용합니다" + +#: common/setting/system.py:1220 +msgid "Enable Machine Ping" +msgstr "장비 핑 사용" + +#: common/setting/system.py:1222 +msgid "Enable periodic ping task of registered machines to check their status" +msgstr "등록된 장비의 상태를 확인하기 위해 주기적으로 핑 작업을 수행합니다" + #: common/setting/user.py:23 msgid "Inline label display" -msgstr "" +msgstr "인라인 라벨 표시" #: common/setting/user.py:25 msgid "Display PDF labels in the browser, instead of downloading as a file" -msgstr "" +msgstr "PDF 라벨을 파일로 다운로드하는 대신 브라우저에서 표시합니다" #: 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 "기본으로 선택될 라벨 프린터를 설정합니다" #: common/setting/user.py:37 msgid "Inline report display" -msgstr "" +msgstr "인라인 보고서 표시" #: common/setting/user.py:39 msgid "Display PDF reports in the browser, instead of downloading as a file" -msgstr "" +msgstr "PDF 보고서를 파일로 다운로드하는 대신 브라우저에서 표시합니다" #: common/setting/user.py:45 msgid "Barcode Scanner in Form Fields" -msgstr "" +msgstr "폼 필드의 바코드 스캐너" #: common/setting/user.py:46 msgid "Allow barcode scanner input in form fields" -msgstr "" +msgstr "폼 필드에서 바코드 스캐너 입력을 허용합니다" #: 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 "검색 미리보기 창에서 비활성 부품을 제외합니다" #: 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 "검색 미리보기 창의 각 섹션에 표시할 결과 수" #: common/setting/user.py:163 msgid "Regex Search" -msgstr "" +msgstr "정규식 검색" #: common/setting/user.py:164 msgid "Enable regular expressions in search queries" -msgstr "" +msgstr "검색 쿼리에서 정규식을 사용할 수 있도록 합니다" #: common/setting/user.py:169 msgid "Whole Word Search" -msgstr "" +msgstr "단어 단위 검색" #: common/setting/user.py:170 msgid "Search queries return results for whole word matches" -msgstr "" +msgstr "검색 쿼리가 단어 전체가 일치하는 결과만 반환합니다" #: common/setting/user.py:175 msgid "Search Notes" -msgstr "" +msgstr "노트 검색" #: common/setting/user.py:177 msgid "Search queries return results for matches from the item's notes" -msgstr "" +msgstr "검색 쿼리가 항목의 노트에서 일치하는 결과를 반환합니다" #: common/setting/user.py:183 msgid "Escape Key Closes Forms" -msgstr "" +msgstr "Esc 키로 폼 닫기" #: common/setting/user.py:184 msgid "Use the escape key to close modal forms" -msgstr "" +msgstr "Esc 키를 사용해 모달 폼을 닫습니다" #: common/setting/user.py:189 msgid "Fixed Navbar" -msgstr "" +msgstr "내비게이션 바 고정" #: common/setting/user.py:190 msgid "The navbar position is fixed to the top of the screen" -msgstr "" +msgstr "내비게이션 바를 화면 상단에 고정합니다" #: common/setting/user.py:195 msgid "Fixed Table Headers" -msgstr "" +msgstr "테이블 헤더 고정" #: common/setting/user.py:196 msgid "Table headers are fixed to the top of the table" -msgstr "" +msgstr "테이블 헤더를 테이블 상단에 고정합니다" #: common/setting/user.py:201 msgid "Show Spotlight" -msgstr "" +msgstr "스포트라이트 표시" #: common/setting/user.py:202 msgid "Enable spotlight navigation functionality" -msgstr "" +msgstr "스포트라이트 내비게이션 기능을 사용합니다" #: common/setting/user.py:207 msgid "Navigation Icons" -msgstr "" +msgstr "내비게이션 아이콘" #: common/setting/user.py:208 msgid "Display icons in the navigation bar" -msgstr "" +msgstr "내비게이션 바에 아이콘을 표시합니다" #: common/setting/user.py:213 msgid "Date Format" -msgstr "" +msgstr "날짜 형식" #: common/setting/user.py:214 msgid "Preferred format for displaying dates" -msgstr "" +msgstr "날짜 표시 기본 형식" #: common/setting/user.py:227 msgid "Show Stock History" -msgstr "" +msgstr "재고 기록 표시" #: common/setting/user.py:228 msgid "Display stock history information in the part detail page" -msgstr "" +msgstr "부품 상세 페이지에 재고 기록 정보를 표시합니다" #: common/setting/user.py:233 msgid "Show Last Breadcrumb" -msgstr "" +msgstr "마지막 탐색 경로 표시" #: common/setting/user.py:234 msgid "Show the current page in breadcrumbs" -msgstr "" +msgstr "탐색 경로(브레드크럼)에서 현재 페이지를 표시" #: common/setting/user.py:239 msgid "Show full stock location in tables" -msgstr "" +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 "" +msgstr "비활성화: 전체 위치 경로를 마우스오버 툴팁으로 표시합니다. 활성화: 전체 위치 경로를 일반 텍스트로 표시합니다." #: common/setting/user.py:247 msgid "Show full part categories in tables" -msgstr "" +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." -msgstr "" +msgstr "비활성화: 전체 카테고리 경로를 마우스오버 툴팁으로 표시합니다. 활성화: 전체 카테고리 경로를 일반 텍스트로 표시합니다." #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" -msgstr "" +msgid "Receive error reports" +msgstr "오류 보고서 수신" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "시스템 오류에 대한 알림을 수신" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "마지막으로 사용한 인쇄 장비" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" +msgstr "사용자의 마지막 사용 인쇄 장비를 저장" + +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" #: common/validators.py:38 msgid "All models" -msgstr "" +msgstr "모든 모델" #: common/validators.py:63 msgid "No attachment model type provided" -msgstr "" +msgstr "첨부 모델 유형이 제공되지 않았습니다" #: common/validators.py:69 msgid "Invalid attachment model type" -msgstr "" +msgstr "잘못된 첨부 모델 유형입니다" #: common/validators.py:110 msgid "Minimum places cannot be greater than maximum places" -msgstr "" +msgstr "최소 자리수는 최대 자리수보다 클 수 없습니다" #: common/validators.py:122 msgid "Maximum places cannot be less than minimum places" -msgstr "" +msgstr "최대 자리수는 최소 자리수보다 작을 수 없습니다" #: common/validators.py:133 msgid "An empty domain is not allowed." -msgstr "" +msgstr "빈 도메인은 허용되지 않습니다." #: common/validators.py:135 #, python-brace-format msgid "Invalid domain name: {domain}" -msgstr "" +msgstr "잘못된 도메인 이름: {domain}" #: common/validators.py:151 msgid "Value must be uppercase" -msgstr "" +msgstr "값은 대문자여야 합니다" #: common/validators.py:157 msgid "Value must be a valid variable identifier" -msgstr "" +msgstr "값은 유효한 변수 식별자여야 합니다" #: company/api.py:141 msgid "Part is Active" -msgstr "" +msgstr "부품이 활성화됨" #: company/api.py:145 msgid "Manufacturer is Active" -msgstr "" - -#: company/api.py:250 -msgid "Supplier Part is Active" -msgstr "" +msgstr "제조사가 활성화됨" #: company/api.py:252 +msgid "Supplier Part is Active" +msgstr "공급업체 부품이 활성화됨" + +#: company/api.py:254 msgid "Primary Supplier Part" -msgstr "" +msgstr "기본 공급업체 부품" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" -msgstr "" +msgstr "내부 부품이 활성화됨" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" -msgstr "" +msgstr "공급업체가 활성화됨" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" -msgstr "" +msgstr "제조사" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" -msgstr "" +msgstr "회사" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" -msgstr "" +msgstr "재고 있음" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" -msgstr "" - -#: company/models.py:152 -msgid "Company description" -msgstr "" +msgstr "회사" #: company/models.py:153 -msgid "Description of the company" -msgstr "" +msgid "Company description" +msgstr "회사 설명" -#: company/models.py:159 -msgid "Website" -msgstr "" +#: company/models.py:154 +msgid "Description of the company" +msgstr "회사에 대한 설명" #: company/models.py:160 +msgid "Website" +msgstr "웹사이트" + +#: company/models.py:161 msgid "Company website URL" -msgstr "" +msgstr "회사 웹사이트 URL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" -msgstr "" +msgstr "전화번호" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" -msgstr "" +msgstr "연락처 전화번호" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" -msgstr "" +msgstr "연락처 이메일 주소" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" -msgstr "" +msgstr "담당자" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" -msgstr "" +msgstr "담당자" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" -msgstr "" +msgstr "외부 회사 정보 링크" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" -msgstr "" - -#: company/models.py:198 -msgid "Is customer" -msgstr "" +msgstr "이 회사가 활성 상태인가요?" #: company/models.py:199 -msgid "Do you sell items to this company?" -msgstr "" +msgid "Is customer" +msgstr "고객 여부" -#: company/models.py:204 -msgid "Is supplier" -msgstr "" +#: company/models.py:200 +msgid "Do you sell items to this company?" +msgstr "이 회사에 품목을 판매하나요?" #: company/models.py:205 -msgid "Do you purchase items from this company?" -msgstr "" +msgid "Is supplier" +msgstr "공급업체 여부" -#: company/models.py:210 -msgid "Is manufacturer" -msgstr "" +#: company/models.py:206 +msgid "Do you purchase items from this company?" +msgstr "이 회사로부터 품목을 구매하나요?" #: company/models.py:211 +msgid "Is manufacturer" +msgstr "제조사 여부" + +#: company/models.py:212 msgid "Does this company manufacture parts?" -msgstr "" +msgstr "이 회사가 부품을 제조하나요?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" -msgstr "" - -#: company/models.py:226 -msgid "Tax ID" -msgstr "" +msgstr "이 회사에서 사용하는 기본 통화" #: company/models.py:227 +msgid "Tax ID" +msgstr "세금 ID" + +#: company/models.py:228 msgid "Company Tax ID" -msgstr "" +msgstr "회사 세금 ID" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" -msgstr "" +msgstr "주소" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" -msgstr "" - -#: company/models.py:400 -msgid "Select company" -msgstr "" +msgstr "주소" #: company/models.py:405 +msgid "Select company" +msgstr "회사 선택" + +#: company/models.py:410 msgid "Address title" -msgstr "" +msgstr "주소 제목" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" -msgstr "" +msgstr "주소 항목을 설명하는 제목" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" -msgstr "" - -#: company/models.py:413 -msgid "Set as primary address" -msgstr "" +msgstr "기본 주소" #: company/models.py:418 +msgid "Set as primary address" +msgstr "기본 주소로 설정" + +#: company/models.py:423 msgid "Line 1" -msgstr "" +msgstr "주소 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" -msgstr "" +msgstr "주소 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" -msgstr "" +msgstr "주소 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" -msgstr "" +msgstr "주소 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" -msgstr "" +msgstr "우편번호" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" -msgstr "" +msgstr "도시/지역" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" -msgstr "" +msgstr "우편번호 도시/지역" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" -msgstr "" +msgstr "주/도" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" -msgstr "" +msgstr "주 또는 도" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" -msgstr "" +msgstr "국가" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" -msgstr "" +msgstr "주소 국가" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" -msgstr "" +msgstr "택배 배송 메모" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" -msgstr "" +msgstr "택배 배송을 위한 메모" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" -msgstr "" +msgstr "내부 배송 메모" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" -msgstr "" +msgstr "내부용 배송 메모" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" -msgstr "" +msgstr "주소 정보 링크(외부)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" -msgstr "" +msgstr "제조사 부품" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" -msgstr "" +msgstr "기본 부품" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" -msgstr "" +msgstr "부품 선택" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" -msgstr "" +msgstr "제조사 선택" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" -msgstr "" +msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" -msgstr "" +msgstr "제조사 부품 번호" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" -msgstr "" +msgstr "외부 제조사 부품 링크 URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" -msgstr "" +msgstr "제조사 부품 설명" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" -msgstr "" +msgstr "포장 단위는 기본 부품 단위와 호환되어야 합니다" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" -msgstr "" +msgstr "포장 단위는 0보다 커야 합니다" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" -msgstr "" +msgstr "연결된 제조사 부품은 동일한 기본 부품을 참조해야 합니다" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" -msgstr "" +msgstr "공급업체" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" -msgstr "" +msgstr "공급업체 선택" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" -msgstr "" - -#: company/models.py:782 -msgid "Is this supplier part active?" -msgstr "" +msgstr "공급업체 SKU" #: company/models.py:787 +msgid "Is this supplier part active?" +msgstr "이 공급업체 부품이 활성 상태인가요?" + +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "기본" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgstr "연결된 부품의 기본 공급업체 부품인가요?" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" -msgstr "" +msgstr "제조사 부품 선택" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" -msgstr "" +msgstr "외부 공급업체 부품 링크 URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" -msgstr "" +msgstr "공급업체 부품 설명" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" -msgstr "" +msgstr "기본 비용" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" -msgstr "" +msgstr "최소 요금(예: 보관 수수료)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" -msgstr "" - -#: company/models.py:839 -msgid "Part packaging" -msgstr "" +msgstr "포장" #: company/models.py:844 +msgid "Part packaging" +msgstr "부품 포장" + +#: company/models.py:849 msgid "Pack Quantity" -msgstr "" +msgstr "포장 수량" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." -msgstr "" +msgstr "한 포장에 공급되는 총 수량입니다. 단품인 경우 비워 두세요." -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" -msgstr "" +msgstr "배수" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" -msgstr "" +msgstr "주문 배수" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" -msgstr "" +msgstr "공급업체에서 제공 가능한 수량" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" -msgstr "" +msgstr "가용성 업데이트됨" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" -msgstr "" +msgstr "가용성 데이터의 마지막 업데이트 날짜" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" -msgstr "" +msgstr "공급업체 가격 구간" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" -msgstr "" +msgstr "이 공급업체에서 사용하는 기본 통화" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" -msgstr "" +msgstr "회사명" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" -msgstr "" +msgstr "재고 있음" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" -msgstr "" +msgstr "가격 구간" + +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "표시 이름" #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" -msgstr "" +msgstr "데이터 내보내기 중 오류가 발생했습니다" #: data_exporter/mixins.py:395 msgid "Data export plugin returned incorrect data format" -msgstr "" +msgstr "데이터 내보내기 플러그인이 잘못된 데이터 형식을 반환했습니다" #: data_exporter/serializers.py:73 msgid "Export Format" -msgstr "" +msgstr "내보내기 형식" #: data_exporter/serializers.py:74 msgid "Select export file format" -msgstr "" +msgstr "내보내기 파일 형식을 선택하세요" #: data_exporter/serializers.py:81 msgid "Export Plugin" -msgstr "" +msgstr "내보내기 플러그인" #: data_exporter/serializers.py:82 msgid "Select export plugin" -msgstr "" +msgstr "내보내기 플러그인을 선택하세요" #: generic/states/fields.py:146 msgid "Additional status information for this item" -msgstr "" +msgstr "이 항목에 대한 추가 상태 정보" #: generic/states/fields.py:160 msgid "Custom status key" -msgstr "" +msgstr "사용자 정의 상태 키" #: generic/states/serializers.py:26 msgid "Custom" -msgstr "" +msgstr "사용자 정의" #: generic/states/serializers.py:37 msgid "Class" -msgstr "" +msgstr "클래스" #: generic/states/serializers.py:40 msgid "Values" -msgstr "" +msgstr "값" #: generic/states/tests.py:22 order/status_codes.py:13 msgid "Placed" -msgstr "" +msgstr "접수됨" #: generic/states/validators.py:21 msgid "Invalid status code" -msgstr "" +msgstr "잘못된 상태 코드" #: importer/models.py:74 msgid "Data File" -msgstr "" +msgstr "데이터 파일" #: importer/models.py:75 msgid "Data file to import" -msgstr "" +msgstr "가져올 데이터 파일" #: importer/models.py:84 msgid "Columns" -msgstr "" +msgstr "열" #: importer/models.py:91 msgid "Target model type for this import session" -msgstr "" +msgstr "이 가져오기 세션의 대상 모델 유형" #: importer/models.py:97 msgid "Import status" -msgstr "" +msgstr "가져오기 상태" #: importer/models.py:107 msgid "Field Defaults" -msgstr "" +msgstr "필드 기본값" #: importer/models.py:114 msgid "Field Overrides" -msgstr "" +msgstr "필드 재정의" #: importer/models.py:121 msgid "Field Filters" -msgstr "" +msgstr "필드 필터" #: importer/models.py:127 msgid "Update Existing Records" -msgstr "" +msgstr "기존 레코드 업데이트" #: importer/models.py:128 msgid "If enabled, existing records will be updated with new data" -msgstr "" +msgstr "활성화하면 기존 레코드가 새 데이터로 업데이트됩니다" #: importer/models.py:281 msgid "Some required fields have not been mapped" -msgstr "" +msgstr "일부 필수 필드가 매핑되지 않았습니다" #: importer/models.py:388 msgid "ID" -msgstr "" +msgstr "ID" #: importer/models.py:389 msgid "Existing database identifier for the record" -msgstr "" +msgstr "레코드의 기존 데이터베이스 식별자" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" -msgstr "" +msgstr "열이 이미 데이터베이스 필드에 매핑되어 있습니다" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" -msgstr "" +msgstr "필드가 이미 데이터 열에 매핑되어 있습니다" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" -msgstr "" - -#: importer/models.py:471 -msgid "Column does not exist in the data file" -msgstr "" +msgstr "열 매핑은 유효한 가져오기 세션에 연결되어야 합니다" #: importer/models.py:478 +msgid "Column does not exist in the data file" +msgstr "데이터 파일에 해당 열이 없습니다" + +#: importer/models.py:485 msgid "Field does not exist in the target model" -msgstr "" +msgstr "대상 모델에 해당 필드가 없습니다" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" -msgstr "" +msgstr "선택한 필드는 읽기 전용입니다" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" -msgstr "" +msgstr "가져오기 세션" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" -msgstr "" +msgstr "필드" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" -msgstr "" +msgstr "열" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" -msgstr "" +msgstr "행 인덱스" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" -msgstr "" +msgstr "원본 행 데이터" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" -msgstr "" +msgstr "오류" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" -msgstr "" - -#: importer/models.py:833 -msgid "ID is required for updating existing records." -msgstr "" - -#: importer/models.py:840 -msgid "No record found with the provided ID" -msgstr "" +msgstr "유효" #: importer/models.py:846 +msgid "ID is required for updating existing records." +msgstr "기존 레코드를 업데이트하려면 ID가 필요합니다." + +#: importer/models.py:853 +msgid "No record found with the provided ID" +msgstr "제공된 ID로 레코드를 찾을 수 없습니다" + +#: importer/models.py:859 msgid "Invalid ID format provided" -msgstr "" +msgstr "잘못된 ID 형식이 제공되었습니다" #: importer/operations.py:31 importer/operations.py:52 msgid "Unsupported data file format" -msgstr "" +msgstr "지원되지 않는 데이터 파일 형식" #: importer/operations.py:43 msgid "Failed to open data file" -msgstr "" +msgstr "데이터 파일을 열지 못했습니다" #: importer/operations.py:54 msgid "Invalid data file dimensions" -msgstr "" +msgstr "잘못된 데이터 파일 크기입니다" #: importer/serializers.py:92 msgid "Invalid field defaults" -msgstr "" +msgstr "잘못된 필드 기본값" #: importer/serializers.py:105 msgid "Invalid field overrides" -msgstr "" +msgstr "잘못된 필드 재정의" #: importer/serializers.py:118 msgid "Invalid field filters" -msgstr "" +msgstr "잘못된 필드 필터" #: importer/serializers.py:177 msgid "Rows" -msgstr "" +msgstr "행" #: importer/serializers.py:178 msgid "List of row IDs to accept" -msgstr "" +msgstr "승인할 행 ID 목록" #: importer/serializers.py:191 msgid "No rows provided" -msgstr "" +msgstr "제공된 행이 없습니다" #: importer/serializers.py:195 msgid "Row does not belong to this session" -msgstr "" +msgstr "행이 이 세션에 속하지 않습니다" #: importer/serializers.py:198 msgid "Row contains invalid data" -msgstr "" +msgstr "행에 잘못된 데이터가 포함되어 있습니다" #: importer/serializers.py:201 msgid "Row has already been completed" -msgstr "" +msgstr "행이 이미 완료되었습니다" #: importer/status_codes.py:13 msgid "Initializing" -msgstr "" +msgstr "초기화 중" #: importer/status_codes.py:18 msgid "Mapping Columns" -msgstr "" +msgstr "열 매핑 중" #: importer/status_codes.py:21 msgid "Importing Data" -msgstr "" +msgstr "데이터 가져오는 중" #: importer/status_codes.py:24 msgid "Processing Data" -msgstr "" +msgstr "데이터 처리 중" #: 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 "데이터 파일에 헤더가 없습니다" #: importer/validators.py:29 msgid "Data file contains too many columns" -msgstr "" +msgstr "데이터 파일에 열이 너무 많습니다" #: importer/validators.py:32 msgid "Data file contains too many rows" -msgstr "" +msgstr "데이터 파일에 행이 너무 많습니다" #: importer/validators.py:53 msgid "Value must be a valid dictionary object" -msgstr "" +msgstr "값은 유효한 사전(dictionary) 객체여야 합니다" #: machine/machine_types/label_printer.py:212 msgid "Copies" -msgstr "" +msgstr "복사본" #: machine/machine_types/label_printer.py:213 msgid "Number of copies to print for each label" -msgstr "" +msgstr "각 라벨에 대해 인쇄할 복사본 수" #: machine/machine_types/label_printer.py:231 msgid "Connected" -msgstr "" +msgstr "연결됨" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" -msgstr "" +msgstr "알 수 없음" #: machine/machine_types/label_printer.py:233 msgid "Printing" -msgstr "" +msgstr "인쇄 중" #: machine/machine_types/label_printer.py:234 msgid "Warning" -msgstr "" +msgstr "경고" #: machine/machine_types/label_printer.py:235 msgid "No media" -msgstr "" +msgstr "미디어 없음" #: machine/machine_types/label_printer.py:236 msgid "Paper jam" -msgstr "" +msgstr "용지 걸림" #: machine/machine_types/label_printer.py:237 msgid "Disconnected" -msgstr "" +msgstr "연결 끊김" #: machine/machine_types/label_printer.py:238 msgid "Error" -msgstr "" +msgstr "오류" #: machine/machine_types/label_printer.py:245 msgid "Label Printer" -msgstr "" +msgstr "라벨 프린터" #: machine/machine_types/label_printer.py:246 msgid "Directly print labels for various items." -msgstr "" +msgstr "다양한 항목의 라벨을 직접 인쇄합니다." #: machine/machine_types/label_printer.py:252 msgid "Printer Location" -msgstr "" +msgstr "프린터 위치" #: machine/machine_types/label_printer.py:253 msgid "Scope the printer to a specific location" -msgstr "" +msgstr "프린터 범위를 특정 위치로 제한합니다" #: machine/models.py:26 msgid "Name of machine" -msgstr "" +msgstr "장비 이름" #: machine/models.py:30 msgid "Machine Type" -msgstr "" +msgstr "장비 유형" #: machine/models.py:30 msgid "Type of machine" -msgstr "" +msgstr "장비의 유형" #: machine/models.py:35 machine/models.py:147 msgid "Driver" -msgstr "" +msgstr "드라이버" #: machine/models.py:36 msgid "Driver used for the machine" -msgstr "" +msgstr "장비에 사용되는 드라이버" #: machine/models.py:40 msgid "Machines can be disabled" -msgstr "" +msgstr "장비를 비활성화할 수 있습니다" #: machine/models.py:96 msgid "Driver available" -msgstr "" +msgstr "사용 가능한 드라이버" #: machine/models.py:101 msgid "No errors" -msgstr "" +msgstr "오류 없음" #: machine/models.py:106 msgid "Initialized" -msgstr "" +msgstr "초기화됨" #: machine/models.py:118 msgid "Machine status" -msgstr "" +msgstr "장비 상태" #: machine/models.py:146 msgid "Machine" -msgstr "" +msgstr "장비" #: machine/models.py:158 msgid "Machine Config" -msgstr "" +msgstr "장비 구성" #: machine/models.py:163 msgid "Config type" -msgstr "" +msgstr "구성 유형" #: machine/serializers.py:24 msgid "Key of the property" -msgstr "" +msgstr "속성 키" #: machine/serializers.py:27 msgid "Value of the property" -msgstr "" +msgstr "속성 값" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" -msgstr "" +msgstr "그룹" #: machine/serializers.py:30 msgid "Grouping of the property" -msgstr "" +msgstr "속성 그룹" #: machine/serializers.py:33 msgid "Type" -msgstr "" +msgstr "유형" #: machine/serializers.py:35 msgid "Type of the property" -msgstr "" +msgstr "속성의 유형" #: machine/serializers.py:40 msgid "Max Progress" -msgstr "" +msgstr "최대 진행도" #: machine/serializers.py:41 msgid "Maximum value for progress type, required if type=progress" -msgstr "" +msgstr "진행도 유형의 최대값( type=progress 인 경우 필수)" #: order/api.py:130 msgid "Order Reference" -msgstr "" +msgstr "주문 참조" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" -msgstr "" +msgstr "미결" #: order/api.py:174 msgid "Has Project Code" -msgstr "" +msgstr "프로젝트 코드 있음" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" -msgstr "" +msgstr "생성자" #: order/api.py:192 msgid "Created Before" -msgstr "" +msgstr "이전 생성" #: order/api.py:196 msgid "Created After" -msgstr "" +msgstr "이후 생성" #: order/api.py:200 msgid "Has Start Date" -msgstr "" +msgstr "시작일 있음" #: order/api.py:208 msgid "Start Date Before" -msgstr "" +msgstr "시작일 이전" #: order/api.py:212 msgid "Start Date After" -msgstr "" +msgstr "시작일 이후" #: order/api.py:216 msgid "Has Target Date" -msgstr "" +msgstr "목표일 있음" #: order/api.py:224 msgid "Target Date Before" -msgstr "" +msgstr "목표일 이전" #: order/api.py:228 msgid "Target Date After" -msgstr "" +msgstr "목표일 이후" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "이전 업데이트" + +#: order/api.py:236 +msgid "Updated After" +msgstr "이후 업데이트" + +#: order/api.py:287 msgid "Has Pricing" -msgstr "" +msgstr "가격 정보 있음" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" -msgstr "" +msgstr "완료일 이전" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" -msgstr "" +msgstr "완료일 이후" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" -msgstr "" +msgstr "외주 생산 작업 지시서" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" -msgstr "" +msgstr "주문" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" -msgstr "" +msgstr "주문 완료" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" -msgstr "" +msgstr "내부 부품" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" -msgstr "" +msgstr "주문 대기" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" -msgstr "" +msgstr "완료됨" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" -msgstr "" +msgstr "배송 있음" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "배송을 찾을 수 없습니다" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" -msgstr "" +msgstr "구매 주문" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: 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 #: 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 msgid "Total price for this order" -msgstr "" +msgstr "이 주문의 총액" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" -msgstr "" +msgstr "주문 통화" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" -msgstr "" +msgstr "이 주문의 통화(비워 두면 회사 기본값 사용)" #: order/models.py:326 msgid "This order is locked and cannot be modified" -msgstr "" +msgstr "이 주문은 잠겨 있어 수정할 수 없습니다" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" -msgstr "" +msgstr "담당자가 선택한 회사와 일치하지 않습니다" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" -msgstr "" +msgstr "시작일은 목표일보다 이전이어야 합니다" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" -msgstr "" +msgstr "주소가 선택한 회사와 일치하지 않습니다" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" -msgstr "" +msgstr "주문 설명(선택 사항)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" -msgstr "" +msgstr "이 주문의 프로젝트 코드를 선택하세요" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" -msgstr "" +msgstr "외부 페이지 링크" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" -msgstr "" +msgstr "시작일" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" -msgstr "" +msgstr "이 주문의 예정 시작일" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" -msgstr "" +msgstr "목표일" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." -msgstr "" +msgstr "주문 배송 예상일입니다. 이 날짜 이후에는 주문이 기한 초과로 표시됩니다." -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" -msgstr "" +msgstr "발행일" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" -msgstr "" +msgstr "주문이 발행된 날짜" #: order/models.py:506 +msgid "Updated At" +msgstr "업데이트 일시" + +#: order/models.py:515 msgid "User or group responsible for this order" -msgstr "" +msgstr "이 주문을 담당하는 사용자 또는 그룹" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" -msgstr "" +msgstr "이 주문의 연락 담당자" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" -msgstr "" +msgstr "이 주문의 회사 주소" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" -msgstr "" +msgstr "주문 참조" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" -msgstr "" +msgstr "상태" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" -msgstr "" +msgstr "구매 주문 상태" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" -msgstr "" +msgstr "품목을 주문하는 공급업체" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" -msgstr "" +msgstr "공급업체 참조" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" -msgstr "" +msgstr "공급업체 주문 참조 코드" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" -msgstr "" +msgstr "수령자" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" -msgstr "" +msgstr "주문이 완료된 날짜" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" -msgstr "" +msgstr "목적지" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" -msgstr "" +msgstr "수령된 품목의 목적지" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" -msgstr "" +msgstr "부품 공급업체는 구매 주문 공급업체와 일치해야 합니다" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" -msgstr "" +msgstr "라인 항목이 구매 주문과 일치하지 않습니다" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" -msgstr "" +msgstr "라인 항목에 연결된 부품이 없습니다" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" -msgstr "" +msgstr "수량은 양수여야 합니다" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" -msgstr "" +msgstr "고객" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" -msgstr "" +msgstr "품목을 판매하는 대상 회사" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" -msgstr "" +msgstr "판매 주문 상태" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " -msgstr "" +msgstr "고객 참조" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" -msgstr "" +msgstr "고객 주문 참조 코드" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" -msgstr "" +msgstr "발송일" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" -msgstr "" +msgstr "발송자" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" -msgstr "" +msgstr "주문이 이미 완료되었습니다" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" -msgstr "" +msgstr "주문이 이미 취소되었습니다" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" -msgstr "" +msgstr "열린 주문만 완료로 표시할 수 있습니다" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" -msgstr "" +msgstr "미완료 발송이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" -msgstr "" +msgstr "미완료 할당이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" -msgstr "" +msgstr "미완료 라인 항목이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" -msgstr "" +msgstr "이 주문은 잠겨 있어 수정할 수 없습니다" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" -msgstr "" - -#: order/models.py:1777 -msgid "Line item reference" -msgstr "" - -#: order/models.py:1784 -msgid "Line item notes" -msgstr "" - -#: order/models.py:1799 -msgid "Target date for this line item (leave blank to use the target date from the order)" -msgstr "" +msgstr "품목 수량" #: order/models.py:1829 -msgid "Line item description (optional)" -msgstr "" +msgid "Line Number" +msgstr "라인 번호" -#: order/models.py:1836 -msgid "Additional context for this line" -msgstr "" +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "이 항목의 라인 번호(선택)" + +#: order/models.py:1839 +msgid "Line item reference" +msgstr "라인 항목 참조" #: order/models.py:1846 +msgid "Line item notes" +msgstr "라인 항목 메모" + +#: order/models.py:1861 +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 "" +msgstr "단가" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" -msgstr "" +msgstr "구매 주문 라인 항목" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" -msgstr "" +msgstr "공급업체 부품은 공급업체와 일치해야 합니다" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" -msgstr "" +msgstr "빌드 주문은 외부로 표시되어야 합니다" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" -msgstr "" +msgstr "빌드 주문은 조립 부품에만 연결할 수 있습니다" -#: order/models.py:1910 +#: 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:1945 +#: order/models.py:2023 msgid "Supplier part" -msgstr "" +msgstr "공급업체 부품" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" -msgstr "" +msgstr "수령됨" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" -msgstr "" +msgstr "수령된 품목 수" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" -msgstr "" - -#: order/models.py:1962 -msgid "Unit purchase price" -msgstr "" - -#: order/models.py:1978 -msgid "External Build Order to be fulfilled by this line item" -msgstr "" +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 "" +msgstr "구매 주문 추가 라인" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" -msgstr "" +msgstr "판매 주문 라인 항목" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" -msgstr "" +msgstr "판매 가능한 부품만 판매 주문에 할당할 수 있습니다" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" -msgstr "" +msgstr "판매 가격" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" -msgstr "" +msgstr "단위 판매 가격" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" -msgstr "" +msgstr "발송됨" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" -msgstr "" - -#: order/models.py:2242 -msgid "Sales Order Shipment" -msgstr "" - -#: order/models.py:2255 -msgid "Shipment address must match the customer" -msgstr "" - -#: order/models.py:2291 -msgid "Shipping address for this shipment" -msgstr "" - -#: order/models.py:2299 -msgid "Date of shipment" -msgstr "" - -#: order/models.py:2305 -msgid "Delivery Date" -msgstr "" - -#: order/models.py:2306 -msgid "Date of delivery of shipment" -msgstr "" - -#: order/models.py:2314 -msgid "Checked By" -msgstr "" - -#: order/models.py:2315 -msgid "User who checked this shipment" -msgstr "" - -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 -#: report/templates/report/inventree_sales_order_shipment_report.html:14 -msgid "Shipment" -msgstr "" +msgstr "발송 수량" #: order/models.py:2323 +msgid "Sales Order Shipment" +msgstr "판매 주문 발송" + +#: order/models.py:2336 +msgid "Shipment address must match the customer" +msgstr "발송 주소는 고객과 일치해야 합니다" + +#: order/models.py:2372 +msgid "Shipping address for this shipment" +msgstr "이 발송의 배송지 주소" + +#: order/models.py:2380 +msgid "Date of shipment" +msgstr "발송 날짜" + +#: order/models.py:2386 +msgid "Delivery Date" +msgstr "배송일" + +#: order/models.py:2387 +msgid "Date of delivery of shipment" +msgstr "발송물 배송 날짜" + +#: order/models.py:2395 +msgid "Checked By" +msgstr "확인자" + +#: order/models.py:2396 +msgid "User who checked this shipment" +msgstr "이 발송을 확인한 사용자" + +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 +#: report/templates/report/inventree_sales_order_shipment_report.html:14 +msgid "Shipment" +msgstr "발송" + +#: order/models.py:2404 msgid "Shipment number" -msgstr "" +msgstr "발송 번호" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" -msgstr "" +msgstr "운송장 번호" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" -msgstr "" +msgstr "발송 추적 정보" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" -msgstr "" +msgstr "송장 번호" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" -msgstr "" +msgstr "연결된 송장의 참조 번호" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" -msgstr "" +msgstr "발송이 이미 전송되었습니다" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" -msgstr "" +msgstr "발송에 할당된 재고 품목이 없습니다" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" -msgstr "" +msgstr "발송은 완료하기 전에 확인되어야 합니다" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" -msgstr "" +msgstr "판매 주문 추가 라인" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" -msgstr "" +msgstr "판매 주문 할당" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" -msgstr "" +msgstr "재고 품목이 할당되지 않았습니다" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" -msgstr "" +msgstr "부품이 다른 라인에 재고 품목을 할당할 수 없습니다" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" -msgstr "" +msgstr "부품이 없는 라인에는 재고를 할당할 수 없습니다" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" -msgstr "" +msgstr "할당 수량은 재고 수량을 초과할 수 없습니다" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" -msgstr "" +msgstr "할당 수량은 0보다 커야 합니다" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" -msgstr "" +msgstr "일련번호가 있는 재고 품목의 수량은 1이어야 합니다" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" -msgstr "" +msgstr "판매 주문이 발송과 일치하지 않습니다" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" -msgstr "" +msgstr "발송이 판매 주문과 일치하지 않습니다" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" -msgstr "" +msgstr "라인" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" -msgstr "" +msgstr "판매 주문 발송 참조" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" -msgstr "" +msgstr "품목" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" -msgstr "" +msgstr "할당할 재고 품목을 선택하세요" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" -msgstr "" +msgstr "재고 할당 수량을 입력하세요" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" -msgstr "" +msgstr "반품 주문 참조" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" -msgstr "" +msgstr "품목이 반품되는 회사" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" -msgstr "" +msgstr "반품 주문 상태" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" -msgstr "" +msgstr "반품 주문 라인 항목" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" -msgstr "" +msgstr "재고 품목을 지정해야 합니다" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" -msgstr "" +msgstr "반품 수량이 재고 수량을 초과합니다" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" -msgstr "" +msgstr "반품 수량은 0보다 커야 합니다" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" -msgstr "" +msgstr "일련번호가 있는 재고 품목에 대한 수량이 올바르지 않습니다" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" -msgstr "" +msgstr "고객에게서 반품받을 품목을 선택하세요" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" -msgstr "" +msgstr "수령일" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" -msgstr "" +msgstr "이 반품 품목을 수령한 날짜" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" -msgstr "" +msgstr "결과" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" -msgstr "" +msgstr "이 라인 항목의 결과" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" -msgstr "" +msgstr "이 라인 항목의 반품 또는 수리에 관련된 비용" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" -msgstr "" +msgstr "반품 주문 추가 라인" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" -msgstr "" +msgstr "주문 ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" -msgstr "" +msgstr "복제할 주문의 ID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" -msgstr "" +msgstr "라인 복사" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" -msgstr "" +msgstr "원본 주문에서 라인 항목을 복사" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" -msgstr "" +msgstr "추가 라인 복사" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" -msgstr "" +msgstr "원본 주문에서 추가 라인 항목을 복사" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" -msgstr "" +msgstr "라인 항목" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" -msgstr "" +msgstr "완료된 라인" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" -msgstr "" +msgstr "주문 복제" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" -msgstr "" +msgstr "이 주문을 복제하기 위한 옵션을 지정하세요" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" -msgstr "" +msgstr "유효하지 않은 주문 ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" -msgstr "" +msgstr "공급업체 이름" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" -msgstr "" +msgstr "주문을 취소할 수 없습니다" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" -msgstr "" +msgstr "미완료 라인 항목이 있어도 주문을 종료할 수 있도록 허용" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" -msgstr "" +msgstr "주문에 미완료 라인 항목이 있습니다" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" -msgstr "" +msgstr "주문이 열려 있지 않습니다" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" -msgstr "" +msgstr "자동 가격 책정" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" -msgstr "" +msgstr "공급업체 부품 데이터를 기반으로 구매 가격을 자동으로 계산" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" -msgstr "" +msgstr "구매 가격 통화" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" -msgstr "" +msgstr "항목 병합" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" -msgstr "" +msgstr "부품, 목적지, 목표일이 같은 항목을 하나의 라인 항목으로 병합" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" -msgstr "" +msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" -msgstr "" +msgstr "내부 부품 번호" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" -msgstr "" +msgstr "내부 부품 이름" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" -msgstr "" +msgstr "공급업체 부품을 지정해야 합니다" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" -msgstr "" +msgstr "구매 주문을 지정해야 합니다" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" -msgstr "" +msgstr "공급업체는 구매 주문과 일치해야 합니다" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" -msgstr "" +msgstr "구매 주문은 공급업체와 일치해야 합니다" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" -msgstr "" +msgstr "라인 항목" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" -msgstr "" +msgstr "수령 품목의 목적지 위치를 선택하세요" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" -msgstr "" +msgstr "입고 재고 품목의 배치 코드를 입력하세요" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" -msgstr "" +msgstr "만료일" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" -msgstr "" +msgstr "입고 재고 품목의 만료일을 입력하세요" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" -msgstr "" +msgstr "입고 재고 품목의 일련번호를 입력하세요" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" -msgstr "" +msgstr "입고 재고 품목의 포장 정보를 재정의" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" -msgstr "" +msgstr "입고 재고 품목에 대한 추가 메모" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" -msgstr "" +msgstr "바코드" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" -msgstr "" +msgstr "스캔된 바코드" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" -msgstr "" +msgstr "바코드가 이미 사용 중입니다" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" -msgstr "" +msgstr "라인 항목을 제공해야 합니다" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" -msgstr "" +msgstr "목적지 위치를 지정해야 합니다" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" -msgstr "" +msgstr "제공된 바코드 값은 고유해야 합니다" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" -msgstr "" +msgstr "발송" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" -msgstr "" +msgstr "완료된 발송" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" -msgstr "" +msgstr "할당된 라인" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" -msgstr "" +msgstr "판매 가격 통화" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" -msgstr "" +msgstr "할당된 품목" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" -msgstr "" +msgstr "발송 세부 정보가 제공되지 않았습니다" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" -msgstr "" +msgstr "라인 항목이 이 주문과 연결되어 있지 않습니다" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" +msgstr "수량은 양수여야 합니다" + +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" -msgstr "" +msgstr "할당할 일련번호를 입력하세요" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" -msgstr "" +msgstr "발송이 이미 발송되었습니다" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" -msgstr "" +msgstr "발송이 이 주문과 연결되어 있지 않습니다" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" -msgstr "" +msgstr "다음 일련번호에 대한 일치 항목을 찾을 수 없습니다" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" -msgstr "" +msgstr "다음 일련번호는 사용할 수 없습니다" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" -msgstr "" +msgstr "반품 주문 라인 항목" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" -msgstr "" +msgstr "라인 항목이 반품 주문과 일치하지 않습니다" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" -msgstr "" +msgstr "라인 항목이 이미 수령되었습니다" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" -msgstr "" +msgstr "진행 중인 주문에 대해서만 품목을 수령할 수 있습니다" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" -msgstr "" +msgstr "반품 수량" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" -msgstr "" +msgstr "라인 가격 통화" #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" -msgstr "" +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 msgid "In Progress" -msgstr "" +msgstr "진행 중" #: order/status_codes.py:105 msgid "Return" -msgstr "" +msgstr "반품" #: order/status_codes.py:108 msgid "Repair" -msgstr "" +msgstr "수리" #: order/status_codes.py:111 msgid "Replace" -msgstr "" +msgstr "교체" #: order/status_codes.py:114 msgid "Refund" -msgstr "" +msgstr "환불" #: order/status_codes.py:117 msgid "Reject" -msgstr "" +msgstr "거부" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" -msgstr "" +msgstr "기한 초과 구매 주문" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" -msgstr "" +msgstr "구매 주문 {po}가 이제 기한을 초과했습니다" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" -msgstr "" +msgstr "기한 초과 판매 주문" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" -msgstr "" +msgstr "판매 주문 {so}가 이제 기한을 초과했습니다" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" -msgstr "" +msgstr "기한 초과 반품 주문" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" -msgstr "" +msgstr "반품 주문 {ro}가 이제 기한을 초과했습니다" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" -msgstr "" +msgstr "즐겨찾기" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" -msgstr "" +msgstr "즐겨찾기 카테고리로 필터" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" -msgstr "" +msgstr "깊이" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" -msgstr "" +msgstr "카테고리 깊이로 필터" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" -msgstr "" +msgstr "최상위" + +#: part/api.py:127 +msgid "Filter by top-level categories" +msgstr "최상위 카테고리로 필터" + +#: part/api.py:140 stock/api.py:320 +msgid "Cascade" +msgstr "계층 포함" #: part/api.py:142 -msgid "Filter by top-level categories" -msgstr "" - -#: part/api.py:155 stock/api.py:321 -msgid "Cascade" -msgstr "" - -#: part/api.py:157 msgid "Include sub-categories in filtered results" -msgstr "" +msgstr "필터 결과에 하위 카테고리를 포함" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" -msgstr "" +msgstr "상위" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" -msgstr "" +msgstr "상위 카테고리로 필터" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" -msgstr "" +msgstr "지정된 카테고리 아래의 하위 카테고리를 제외" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" -msgstr "" +msgstr "결과 있음" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" -msgstr "" +msgstr "변형 여부" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" -msgstr "" +msgstr "리비전 여부" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" -msgstr "" +msgstr "리비전 있음" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" -msgstr "" +msgstr "BOM 유효" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" -msgstr "" +msgstr "카테고리 계층 포함" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" -msgstr "" +msgstr "참이면 지정된 카테고리의 하위 카테고리에 있는 항목을 포함합니다" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" -msgstr "" +msgstr "숫자 카테고리 ID 또는 'null' 값으로 필터" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" -msgstr "" +msgstr "조립 부품이 활성 상태" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" +msgstr "조립 부품을 추적할 수 있음" + +#: part/api.py:1307 +msgid "Assembly part is testable" +msgstr "조립 부품을 테스트할 수 있음" + +#: part/api.py:1311 +msgid "Assembly part is locked" msgstr "" #: part/api.py:1316 -msgid "Assembly part is testable" -msgstr "" - -#: part/api.py:1321 msgid "Component part is active" -msgstr "" +msgstr "구성 부품이 활성 상태" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" -msgstr "" +msgstr "구성 부품을 추적할 수 있음" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" -msgstr "" +msgstr "구성 부품을 테스트할 수 있음" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" -msgstr "" +msgstr "구성 부품이 조립품임" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" -msgstr "" +msgstr "구성 부품이 가상 부품임" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" -msgstr "" +msgstr "사용 가능한 재고 있음" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" -msgstr "" +msgstr "사용" #: part/models.py:92 part/models.py:413 #: templates/email/part_event_notification.html:16 msgid "Part Category" -msgstr "" +msgstr "부품 카테고리" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" -msgstr "" +msgstr "부품 카테고리" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" -msgstr "" +msgstr "기본 위치" #: part/models.py:112 msgid "Default location for parts in this category" -msgstr "" +msgstr "이 카테고리의 부품 기본 위치" #: part/models.py:117 stock/models.py:204 msgid "Structural" -msgstr "" +msgstr "구조적" #: part/models.py:119 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." -msgstr "" +msgstr "부품은 구조 카테고리에 직접 할당할 수 없지만, 하위 카테고리에 할당할 수 있습니다." #: part/models.py:128 msgid "Default keywords" -msgstr "" +msgstr "기본 키워드" #: part/models.py:129 msgid "Default keywords for parts in this category" -msgstr "" +msgstr "이 카테고리의 부품 기본 키워드" #: part/models.py:136 stock/models.py:99 stock/models.py:186 msgid "Icon" -msgstr "" +msgstr "아이콘" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" -msgstr "" +msgstr "아이콘(선택)" #: part/models.py:181 msgid "You cannot make this part category structural because some parts are already assigned to it!" -msgstr "" +msgstr "일부 부품이 이미 이 카테고리에 할당되어 있어 이 부품 카테고리를 구조적으로 만들 수 없습니다!" #: part/models.py:369 msgid "Part Category Parameter Template" -msgstr "" +msgstr "부품 카테고리 매개변수 템플릿" #: part/models.py:425 msgid "Default Value" -msgstr "" +msgstr "기본값" #: part/models.py:426 msgid "Default Parameter Value" -msgstr "" +msgstr "기본 매개변수 값" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" -msgstr "" +msgstr "부품" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" -msgstr "" +msgstr "잠긴 부품의 매개변수는 삭제할 수 없습니다" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" -msgstr "" +msgstr "잠긴 부품의 매개변수는 수정할 수 없습니다" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" -msgstr "" +msgstr "잠겨 있어 이 부품을 삭제할 수 없습니다" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" -msgstr "" +msgstr "여전히 활성 상태라 이 부품을 삭제할 수 없습니다" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" -msgstr "" +msgstr "조립품에 사용 중이라 이 부품을 삭제할 수 없습니다" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" -msgstr "" +msgstr "부품 '{self}'은(는) '{parent}'의 BOM에 사용할 수 없습니다(순환 참조)" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" -msgstr "" +msgstr "부품 '{parent}'이(가) '{self}'의 BOM에 사용되고 있습니다(순환 참조)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" -msgstr "" +msgstr "IPN은 정규식 패턴 {pattern}과 일치해야 합니다" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" -msgstr "" +msgstr "부품은 자기 자신의 개정이 될 수 없습니다" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "개정으로 표시된 부품에는 개정 코드가 지정되어야 합니다" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" -msgstr "" +msgstr "개정은 조립 부품에만 허용됩니다" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" -msgstr "" +msgstr "템플릿 부품의 개정을 만들 수 없습니다" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" -msgstr "" +msgstr "상위 부품은 동일한 템플릿을 가리켜야 합니다" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" -msgstr "" +msgstr "이 일련번호의 재고 항목이 이미 존재합니다" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" -msgstr "" +msgstr "부품 설정에서 중복 IPN은 허용되지 않습니다" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." -msgstr "" +msgstr "중복된 부품 개정이 이미 존재합니다." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." -msgstr "" +msgstr "이 이름, IPN 및 개정의 부품이 이미 존재합니다." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" -msgstr "" +msgstr "부품은 구조 부품 카테고리에 할당할 수 없습니다!" + +#: part/models.py:1102 +msgid "Part name" +msgstr "부품 이름" #: part/models.py:1107 -msgid "Part name" -msgstr "" - -#: part/models.py:1112 msgid "Is Template" -msgstr "" +msgstr "템플릿 여부" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" -msgstr "" +msgstr "이 부품은 템플릿 부품인가요?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" -msgstr "" +msgstr "이 부품은 다른 부품의 변형(Variant)인가요?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" -msgstr "" +msgstr "변형 대상" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" -msgstr "" +msgstr "부품 설명(선택)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" -msgstr "" +msgstr "키워드" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" -msgstr "" +msgstr "검색 결과에서 가시성을 높이기 위한 부품 키워드" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" -msgstr "" +msgstr "부품 카테고리" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" -msgstr "" +msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" -msgstr "" +msgstr "부품 개정 또는 버전 번호" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" -msgstr "" +msgstr "개정" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" -msgstr "" +msgstr "이 부품은 다른 부품의 개정인가요?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" -msgstr "" +msgstr "개정 대상" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" -msgstr "" +msgstr "이 항목은 보통 어디에 보관되나요?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" -msgstr "" +msgstr "기본 만료" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" -msgstr "" +msgstr "이 부품의 재고 항목 만료 기간(일)" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" -msgstr "" +msgstr "최소 재고" -#: part/models.py:1238 +#: 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:1247 +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" -msgstr "" +msgstr "이 부품의 측정 단위" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" -msgstr "" +msgstr "이 부품을 다른 부품으로 조립/제작할 수 있나요?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" -msgstr "" +msgstr "이 부품을 사용해 다른 부품을 제작할 수 있나요?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" -msgstr "" +msgstr "이 부품에 고유 항목 추적 기능이 있나요?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" -msgstr "" +msgstr "이 부품에 대한 테스트 결과를 기록할 수 있나요?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" -msgstr "" - -#: part/models.py:1284 -msgid "Can this part be sold to customers?" -msgstr "" +msgstr "이 부품을 외부 공급업체에서 구매할 수 있나요?" #: part/models.py:1288 +msgid "Can this part be sold to customers?" +msgstr "이 부품을 고객에게 판매할 수 있나요?" + +#: part/models.py:1292 msgid "Is this part active?" -msgstr "" +msgstr "이 부품이 활성 상태인가요?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" -msgstr "" +msgstr "잠긴 부품은 편집할 수 없습니다" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" -msgstr "" +msgstr "소프트웨어 제품이나 라이선스 같은 가상 부품인가요?" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" -msgstr "" +msgstr "BOM 검증됨" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" -msgstr "" +msgstr "이 부품의 BOM이 유효한가요?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" -msgstr "" +msgstr "BOM 체크섬" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" -msgstr "" +msgstr "저장된 BOM 체크섬" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" -msgstr "" +msgstr "BOM 검증자" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" -msgstr "" +msgstr "BOM 검증 날짜" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" -msgstr "" +msgstr "생성 사용자" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" -msgstr "" +msgstr "이 부품의 책임 소유자" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" -msgstr "" +msgstr "판매 배수" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" -msgstr "" - -#: part/models.py:3329 -msgid "Minimum BOM Cost" -msgstr "" - -#: part/models.py:3330 -msgid "Minimum cost of component parts" -msgstr "" - -#: part/models.py:3336 -msgid "Maximum BOM Cost" -msgstr "" - -#: part/models.py:3337 -msgid "Maximum cost of component parts" -msgstr "" +msgstr "가격 계산 캐시에 사용되는 통화" #: part/models.py:3343 -msgid "Minimum Purchase Cost" -msgstr "" +msgid "Minimum BOM Cost" +msgstr "최소 BOM 비용" #: part/models.py:3344 -msgid "Minimum historical purchase cost" -msgstr "" +msgid "Minimum cost of component parts" +msgstr "구성 부품의 최소 비용" #: part/models.py:3350 -msgid "Maximum Purchase Cost" -msgstr "" +msgid "Maximum BOM Cost" +msgstr "최대 BOM 비용" #: part/models.py:3351 -msgid "Maximum historical purchase cost" -msgstr "" +msgid "Maximum cost of component parts" +msgstr "구성 부품의 최대 비용" #: part/models.py:3357 -msgid "Minimum Internal Price" -msgstr "" +msgid "Minimum Purchase Cost" +msgstr "최소 구매 비용" #: part/models.py:3358 -msgid "Minimum cost based on internal price breaks" -msgstr "" +msgid "Minimum historical purchase cost" +msgstr "과거 구매 비용의 최소값" #: part/models.py:3364 -msgid "Maximum Internal Price" -msgstr "" +msgid "Maximum Purchase Cost" +msgstr "최대 구매 비용" #: part/models.py:3365 -msgid "Maximum cost based on internal price breaks" -msgstr "" +msgid "Maximum historical purchase cost" +msgstr "과거 구매 비용의 최대값" #: part/models.py:3371 -msgid "Minimum Supplier Price" -msgstr "" +msgid "Minimum Internal Price" +msgstr "최소 내부 가격" #: part/models.py:3372 -msgid "Minimum price of part from external suppliers" -msgstr "" +msgid "Minimum cost based on internal price breaks" +msgstr "내부 가격 구간에 기반한 최소 비용" #: part/models.py:3378 -msgid "Maximum Supplier Price" -msgstr "" +msgid "Maximum Internal Price" +msgstr "최대 내부 가격" #: part/models.py:3379 -msgid "Maximum price of part from external suppliers" -msgstr "" +msgid "Maximum cost based on internal price breaks" +msgstr "내부 가격 구간에 기반한 최대 비용" #: part/models.py:3385 -msgid "Minimum Variant Cost" -msgstr "" +msgid "Minimum Supplier Price" +msgstr "최소 공급업체 가격" #: part/models.py:3386 -msgid "Calculated minimum cost of variant parts" -msgstr "" +msgid "Minimum price of part from external suppliers" +msgstr "외부 공급업체로부터의 최소 가격" #: part/models.py:3392 -msgid "Maximum Variant Cost" -msgstr "" +msgid "Maximum Supplier Price" +msgstr "최대 공급업체 가격" #: part/models.py:3393 -msgid "Calculated maximum cost of variant parts" -msgstr "" +msgid "Maximum price of part from external suppliers" +msgstr "외부 공급업체로부터의 최대 가격" -#: part/models.py:3399 part/models.py:3413 -msgid "Minimum Cost" -msgstr "" +#: part/models.py:3399 +msgid "Minimum Variant Cost" +msgstr "최소 변형 비용" #: part/models.py:3400 -msgid "Override minimum cost" -msgstr "" +msgid "Calculated minimum cost of variant parts" +msgstr "변형 부품의 계산된 최소 비용" -#: part/models.py:3406 part/models.py:3420 -msgid "Maximum Cost" -msgstr "" +#: part/models.py:3406 +msgid "Maximum Variant Cost" +msgstr "최대 변형 비용" #: part/models.py:3407 -msgid "Override maximum cost" -msgstr "" +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 "Calculated overall minimum cost" -msgstr "" +msgid "Override minimum cost" +msgstr "최소 비용 재정의" + +#: part/models.py:3420 part/models.py:3434 +msgid "Maximum Cost" +msgstr "최대 비용" #: part/models.py:3421 -msgid "Calculated overall maximum cost" -msgstr "" - -#: part/models.py:3427 -msgid "Minimum Sale Price" -msgstr "" +msgid "Override maximum cost" +msgstr "최대 비용 재정의" #: part/models.py:3428 -msgid "Minimum sale price based on price breaks" -msgstr "" - -#: part/models.py:3434 -msgid "Maximum Sale Price" -msgstr "" +msgid "Calculated overall minimum cost" +msgstr "계산된 전체 최소 비용" #: part/models.py:3435 -msgid "Maximum sale price based on price breaks" -msgstr "" +msgid "Calculated overall maximum cost" +msgstr "계산된 전체 최대 비용" #: part/models.py:3441 -msgid "Minimum Sale Cost" -msgstr "" +msgid "Minimum Sale Price" +msgstr "최소 판매 가격" #: part/models.py:3442 -msgid "Minimum historical sale price" -msgstr "" +msgid "Minimum sale price based on price breaks" +msgstr "가격 구간에 기반한 최소 판매 가격" #: part/models.py:3448 -msgid "Maximum Sale Cost" -msgstr "" +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:3467 -msgid "Part for stocktake" -msgstr "" - -#: part/models.py:3472 -msgid "Item Count" -msgstr "" - -#: part/models.py:3473 -msgid "Number of individual stock entries at time of stocktake" -msgstr "" +msgstr "과거 판매 가격의 최대값" #: part/models.py:3481 -msgid "Total available stock at time of stocktake" -msgstr "" - -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 -msgid "Date" -msgstr "" +msgid "Part for stocktake" +msgstr "재고 조사 대상 부품" #: part/models.py:3486 -msgid "Date stocktake was performed" -msgstr "" +msgid "Item Count" +msgstr "항목 수" -#: part/models.py:3493 -msgid "Minimum Stock Cost" -msgstr "" +#: part/models.py:3487 +msgid "Number of individual stock entries at time of stocktake" +msgstr "재고 조사 시점의 개별 재고 항목 수" -#: part/models.py:3494 -msgid "Estimated minimum cost of stock on hand" -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 "" +msgstr "최대 재고 비용" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" -msgstr "" +msgstr "보유 재고의 추정 최대 비용" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" -msgstr "" +msgstr "부품 판매 가격 구간" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" -msgstr "" +msgstr "부품 테스트 템플릿" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" -msgstr "" - -#: part/models.py:3683 -msgid "Test templates can only be created for testable parts" -msgstr "" +msgstr "템플릿 이름이 올바르지 않습니다 - 영숫자 문자를 최소 1개 포함해야 합니다" #: part/models.py:3697 +msgid "Test templates can only be created for testable parts" +msgstr "테스트 템플릿은 테스트 가능한 부품에만 만들 수 있습니다" + +#: part/models.py:3711 msgid "Test template with the same key already exists for part" -msgstr "" +msgstr "같은 키의 테스트 템플릿이 이 부품에 이미 존재합니다" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" -msgstr "" - -#: part/models.py:3715 -msgid "Enter a name for the test" -msgstr "" - -#: part/models.py:3721 -msgid "Test Key" -msgstr "" - -#: part/models.py:3722 -msgid "Simplified key for the test" -msgstr "" +msgstr "테스트 이름" #: part/models.py:3729 +msgid "Enter a name for the test" +msgstr "테스트 이름을 입력하세요" + +#: part/models.py:3735 +msgid "Test Key" +msgstr "테스트 키" + +#: part/models.py:3736 +msgid "Simplified key for the test" +msgstr "테스트를 위한 단순화된 키" + +#: part/models.py:3743 msgid "Test Description" -msgstr "" +msgstr "테스트 설명" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" -msgstr "" +msgstr "이 테스트에 대한 설명을 입력하세요" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" -msgstr "" - -#: part/models.py:3739 -msgid "Required" -msgstr "" - -#: part/models.py:3740 -msgid "Is this test required to pass?" -msgstr "" - -#: part/models.py:3745 -msgid "Requires Value" -msgstr "" - -#: part/models.py:3746 -msgid "Does this test require a value when adding a test result?" -msgstr "" - -#: part/models.py:3751 -msgid "Requires Attachment" -msgstr "" +msgstr "이 테스트가 활성화되어 있나요?" #: part/models.py:3753 -msgid "Does this test require a file attachment when adding a test result?" -msgstr "" +msgid "Required" +msgstr "필수" + +#: part/models.py:3754 +msgid "Is this test required to pass?" +msgstr "이 테스트는 통과가 필수인가요?" + +#: part/models.py:3759 +msgid "Requires Value" +msgstr "값 필요" #: part/models.py:3760 +msgid "Does this test require a value when adding a test result?" +msgstr "테스트 결과를 추가할 때 값이 필요한가요?" + +#: part/models.py:3765 +msgid "Requires Attachment" +msgstr "첨부 필요" + +#: part/models.py:3767 +msgid "Does this test require a file attachment when adding a test result?" +msgstr "테스트 결과를 추가할 때 파일 첨부가 필요한가요?" + +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" +msgstr "이 테스트의 유효한 선택지(쉼표로 구분)" + +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3954 +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "수량은 0 이상이어야 합니다" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" -msgstr "" +msgstr "조립품이 잠겨 있어 BOM 항목을 수정할 수 없습니다" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" -msgstr "" +msgstr "변형 조립품이 잠겨 있어 BOM 항목을 수정할 수 없습니다" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" -msgstr "" +msgstr "상위 부품을 선택하세요" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" -msgstr "" +msgstr "하위 부품" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" +msgstr "BOM에 사용할 부품을 선택하세요" + +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" msgstr "" -#: part/models.py:3993 +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" -msgstr "" +msgstr "이 BOM 항목의 BOM 수량" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" -msgstr "" +msgstr "이 BOM 항목은 선택 사항입니다" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" -msgstr "" +msgstr "이 BOM 항목은 소모품입니다(제작 주문에서 추적되지 않음)" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" -msgstr "" +msgstr "설정 수량" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" -msgstr "" +msgstr "설정 손실을 고려해 제작에 추가로 필요한 수량" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" -msgstr "" +msgstr "손실률" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" -msgstr "" +msgstr "제작 손실률 추정치(백분율, 0-100)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" -msgstr "" +msgstr "반올림 배수" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" -msgstr "" +msgstr "필요 생산 수량을 이 값의 가장 가까운 배수로 올림합니다" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" -msgstr "" +msgstr "BOM 항목 참조" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" -msgstr "" +msgstr "BOM 항목 메모" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" -msgstr "" +msgstr "체크섬" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" -msgstr "" +msgstr "BOM 라인 체크섬" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" -msgstr "" +msgstr "검증됨" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" -msgstr "" +msgstr "이 BOM 항목이 검증되었습니다" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" -msgstr "" +msgstr "상속됨" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" -msgstr "" +msgstr "이 BOM 항목은 변형 부품의 BOM에 상속됩니다" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" -msgstr "" +msgstr "변형 부품의 재고 항목을 이 BOM 항목에 사용할 수 있습니다" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" -msgstr "" +msgstr "추적 가능한 부품의 수량은 정수여야 합니다" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" -msgstr "" +msgstr "하위 부품을 지정해야 합니다" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" -msgstr "" - -#: part/models.py:4369 -msgid "Substitute part cannot be the same as the master part" -msgstr "" - -#: part/models.py:4382 -msgid "Parent BOM item" -msgstr "" - -#: part/models.py:4390 -msgid "Substitute part" -msgstr "" - -#: part/models.py:4406 -msgid "Part 1" -msgstr "" - -#: part/models.py:4414 -msgid "Part 2" -msgstr "" - -#: part/models.py:4415 -msgid "Select Related Part" -msgstr "" - -#: part/models.py:4422 -msgid "Note for this relationship" -msgstr "" - -#: part/models.py:4441 -msgid "Part relationship cannot be created between a part and itself" -msgstr "" +msgstr "BOM 항목 대체품" #: part/models.py:4446 +msgid "Substitute part cannot be the same as the master part" +msgstr "대체 부품은 기준 부품과 같을 수 없습니다" + +#: part/models.py:4459 +msgid "Parent BOM item" +msgstr "상위 BOM 항목" + +#: part/models.py:4467 +msgid "Substitute part" +msgstr "대체 부품" + +#: part/models.py:4483 +msgid "Part 1" +msgstr "부품 1" + +#: part/models.py:4491 +msgid "Part 2" +msgstr "부품 2" + +#: part/models.py:4492 +msgid "Select Related Part" +msgstr "관련 부품 선택" + +#: part/models.py:4499 +msgid "Note for this relationship" +msgstr "이 관계에 대한 메모" + +#: part/models.py:4518 +msgid "Part relationship cannot be created between a part and itself" +msgstr "부품과 자기 자신 사이에는 부품 관계를 만들 수 없습니다" + +#: part/models.py:4523 msgid "Duplicate relationship already exists" -msgstr "" +msgstr "중복된 관계가 이미 존재합니다" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" -msgstr "" +msgstr "상위 카테고리" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" -msgstr "" +msgstr "상위 부품 카테고리" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" -msgstr "" +msgstr "하위 카테고리" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" -msgstr "" +msgstr "결과" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" -msgstr "" +msgstr "이 템플릿에 대해 기록된 결과 수" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" -msgstr "" +msgstr "이 재고 항목의 구매 통화" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" -msgstr "" +msgstr "파일이 이미지가 아닙니다" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" -msgstr "" +msgstr "원본 부품" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" -msgstr "" +msgstr "복제할 원본 부품을 선택하세요" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" -msgstr "" +msgstr "이미지 복사" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" -msgstr "" +msgstr "원본 부품의 이미지를 복사합니다" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" -msgstr "" +msgstr "BOM 복사" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" -msgstr "" +msgstr "원본 부품의 자재 명세서(BOM)를 복사합니다" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" -msgstr "" +msgstr "원본 부품의 매개변수 데이터를 복사합니다" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" -msgstr "" +msgstr "메모 복사" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" -msgstr "" +msgstr "원본 부품의 메모를 복사합니다" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" -msgstr "" +msgstr "테스트 복사" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" -msgstr "" +msgstr "원본 부품의 테스트 템플릿을 복사합니다" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" -msgstr "" +msgstr "초기 재고 수량" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." -msgstr "" +msgstr "이 부품의 초기 재고 수량을 지정하세요. 수량이 0이면 재고가 추가되지 않습니다." -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" -msgstr "" +msgstr "초기 재고 위치" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" -msgstr "" +msgstr "이 부품의 초기 재고 위치를 지정하세요" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" -msgstr "" +msgstr "공급업체를 선택하세요(또는 비워 두고 건너뛰기)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" -msgstr "" +msgstr "제조사를 선택하세요(또는 비워 두고 건너뛰기)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" -msgstr "" +msgstr "제조사 부품 번호" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" -msgstr "" - -#: part/serializers.py:505 -msgid "Selected company is not a valid manufacturer" -msgstr "" +msgstr "선택한 회사는 유효한 공급업체가 아닙니다" #: part/serializers.py:516 +msgid "Selected company is not a valid manufacturer" +msgstr "선택한 회사는 유효한 제조사가 아닙니다" + +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" -msgstr "" +msgstr "이 MPN과 일치하는 제조사 부품이 이미 존재합니다" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" -msgstr "" +msgstr "이 SKU와 일치하는 공급업체 부품이 이미 존재합니다" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" -msgstr "" +msgstr "카테고리 이름" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" -msgstr "" +msgstr "제작 중" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" -msgstr "" +msgstr "현재 생산 중인 이 부품의 수량" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" -msgstr "" +msgstr "제작 예정인 이 부품의 미완료 수량" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" -msgstr "" +msgstr "재고 항목" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" -msgstr "" +msgstr "개정" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" -msgstr "" +msgstr "총 재고" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" -msgstr "" +msgstr "미할당 재고" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" -msgstr "" +msgstr "변형 재고" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" -msgstr "" +msgstr "부품 복제" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" -msgstr "" +msgstr "다른 부품에서 초기 데이터를 복사합니다" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" -msgstr "" +msgstr "초기 재고" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" -msgstr "" +msgstr "초기 재고 수량과 함께 부품을 생성합니다" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" -msgstr "" +msgstr "공급업체 정보" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" -msgstr "" +msgstr "이 부품에 대한 초기 공급업체 정보를 추가합니다" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" -msgstr "" +msgstr "카테고리 매개변수 복사" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" -msgstr "" +msgstr "선택한 부품 카테고리의 매개변수 템플릿을 복사합니다" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" -msgstr "" +msgstr "기존 이미지" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" -msgstr "" +msgstr "기존 부품 이미지의 파일명" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" -msgstr "" +msgstr "이미지 파일이 존재하지 않습니다" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" -msgstr "" +msgstr "전체 자재 명세서(BOM) 검증" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" -msgstr "" +msgstr "제작 가능" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" -msgstr "" +msgstr "제작 주문에 필요" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" -msgstr "" +msgstr "제작 주문에 할당됨" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" -msgstr "" +msgstr "판매 주문에 필요" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" -msgstr "" +msgstr "판매 주문에 할당됨" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" -msgstr "" +msgstr "부품 IPN" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "부품 설명" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "재고 조사 정보를 생성할 부품을 선택하세요(및 모든 변형 부품)." -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "해당 카테고리(및 하위 카테고리)의 모든 부품을 포함할 카테고리를 선택하세요" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "해당 위치(하위 위치 포함)에 재고가 있는 모든 부품을 포함할 위치를 선택하세요" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "재고 조사 항목 생성" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "선택한 부품에 대한 재고 조사 항목을 저장합니다" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" -msgstr "" +msgstr "보고서 생성" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" -msgstr "" +msgstr "선택한 부품에 대한 재고 조사 보고서를 생성합니다" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" -msgstr "" +msgstr "최소 가격" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" -msgstr "" +msgstr "계산된 최소 가격 값을 재정의합니다" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" -msgstr "" +msgstr "최소 가격 통화" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" -msgstr "" +msgstr "최대 가격" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" -msgstr "" +msgstr "계산된 최대 가격 값을 재정의합니다" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" -msgstr "" +msgstr "최대 가격 통화" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" -msgstr "" +msgstr "업데이트" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" -msgstr "" +msgstr "이 부품의 가격 정보를 업데이트합니다" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" -msgstr "" +msgstr "제공된 통화를 {default_currency}(으)로 변환할 수 없습니다" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" -msgstr "" +msgstr "최소 가격은 최대 가격보다 클 수 없습니다" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" +msgstr "최대 가격은 최소 가격보다 작을 수 없습니다" + +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1706 msgid "Select the parent assembly" -msgstr "" +msgstr "상위 조립품을 선택하세요" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" +msgstr "구성 부품을 선택하세요" + +#: part/serializers.py:1861 +msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1989 msgid "Select part to copy BOM from" -msgstr "" +msgstr "BOM을 복사할 부품을 선택하세요" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" -msgstr "" +msgstr "기존 데이터 제거" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" -msgstr "" +msgstr "복사하기 전에 기존 BOM 항목을 제거합니다" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" -msgstr "" +msgstr "상속 항목 포함" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" -msgstr "" +msgstr "템플릿 부품에서 상속된 BOM 항목 포함" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" -msgstr "" +msgstr "잘못된 행 건너뛰기" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" -msgstr "" +msgstr "이 옵션을 사용하면 잘못된 행을 건너뜁니다" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" -msgstr "" +msgstr "대체 부품 복사" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" -msgstr "" +msgstr "BOM 항목을 복제할 때 대체 부품도 복사" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" -msgstr "" +msgstr "재고 부족 알림" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" -msgstr "" +msgstr "{part.name}의 사용 가능한 재고가 설정된 최소 수준 아래로 떨어졌습니다" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" -msgstr "" +msgstr "유통기한 임박 재고 알림" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" -msgstr "" +msgstr "유통기한이 임박한 재고 항목이 1개 있습니다" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" -msgstr "" +msgstr "유통기한이 임박한 재고 항목이 {item_count}개 있습니다" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" -msgstr "" +msgstr "유통기한 없음" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" -msgstr "" +msgstr "{abs(days_diff)}일 전에 만료됨" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" -msgstr "" +msgstr "오늘 만료됨" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" -msgstr "" +msgstr "{days_until_expiry}일" #: plugin/api.py:80 msgid "Builtin" -msgstr "" +msgstr "내장" #: plugin/api.py:94 msgid "Mandatory" -msgstr "" +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 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 msgid "No match found for barcode data" -msgstr "" +msgstr "바코드 데이터와 일치하는 항목을 찾을 수 없습니다" #: plugin/base/barcodes/api.py:216 msgid "Match found for barcode data" -msgstr "" +msgstr "바코드 데이터와 일치하는 항목을 찾았습니다" #: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" -msgstr "" +msgstr "지원되지 않는 모델입니다" #: plugin/base/barcodes/api.py:259 msgid "Model instance not found" -msgstr "" +msgstr "모델 인스턴스를 찾을 수 없습니다" #: plugin/base/barcodes/api.py:288 msgid "Barcode matches existing item" -msgstr "" +msgstr "바코드가 기존 항목과 일치합니다" #: 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 "" +msgstr "일치하는 공급업체 부품이 여러 개 있습니다" #: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 msgid "No matching plugin found for barcode data" -msgstr "" +msgstr "바코드 데이터에 일치하는 플러그인을 찾을 수 없습니다" #: plugin/base/barcodes/api.py:461 msgid "Matched supplier part" -msgstr "" +msgstr "공급업체 부품과 일치함" #: plugin/base/barcodes/api.py:529 msgid "Item has already been received" -msgstr "" +msgstr "항목이 이미 입고되었습니다" #: plugin/base/barcodes/api.py:577 msgid "No plugin match for supplier barcode" -msgstr "" +msgstr "공급업체 바코드에 일치하는 플러그인이 없습니다" #: plugin/base/barcodes/api.py:626 msgid "Multiple matching line items found" -msgstr "" +msgstr "일치하는 라인 항목이 여러 개 있습니다" #: plugin/base/barcodes/api.py:629 msgid "No matching line item found" -msgstr "" +msgstr "일치하는 라인 항목을 찾을 수 없습니다" #: plugin/base/barcodes/api.py:675 msgid "No sales order provided" -msgstr "" +msgstr "판매 주문이 제공되지 않았습니다" #: plugin/base/barcodes/api.py:684 msgid "Barcode does not match an existing stock item" -msgstr "" +msgstr "바코드가 기존 재고 항목과 일치하지 않습니다" #: plugin/base/barcodes/api.py:700 msgid "Stock item does not match line item" -msgstr "" +msgstr "재고 항목이 라인 항목과 일치하지 않습니다" #: plugin/base/barcodes/api.py:730 msgid "Insufficient stock available" -msgstr "" +msgstr "사용 가능한 재고가 부족합니다" #: plugin/base/barcodes/api.py:743 msgid "Stock item allocated to sales order" -msgstr "" +msgstr "재고 항목이 판매 주문에 할당되었습니다" #: plugin/base/barcodes/api.py:746 msgid "Not enough information" -msgstr "" +msgstr "정보가 충분하지 않습니다" #: 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 msgid "Supplier part does not match line item" -msgstr "" +msgstr "공급업체 부품이 라인 항목과 일치하지 않습니다" #: plugin/base/barcodes/mixins.py:378 msgid "Line item is already completed" -msgstr "" +msgstr "라인 항목이 이미 완료되었습니다" #: plugin/base/barcodes/mixins.py:415 msgid "Further information required to receive line item" -msgstr "" +msgstr "라인 항목을 입고하려면 추가 정보가 필요합니다" #: plugin/base/barcodes/mixins.py:423 msgid "Received purchase order line item" -msgstr "" +msgstr "구매 주문 라인 항목을 입고했습니다" #: plugin/base/barcodes/mixins.py:430 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 "항목을 입고할 구매 주문" #: plugin/base/barcodes/serializers.py:174 msgid "Purchase order has not been placed" -msgstr "" +msgstr "구매 주문이 발주되지 않았습니다" #: 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 "출하가 이미 배송되었습니다" #: 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:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" -msgstr "" +msgstr "라벨을 PDF로 렌더링하는 중 오류가 발생했습니다" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" -msgstr "" +msgstr "라벨을 HTML로 렌더링하는 중 오류가 발생했습니다" -#: plugin/base/label/mixins.py:144 +#: 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 "바코드에 대한 기본 지원을 제공합니다" #: plugin/builtin/barcodes/inventree_barcode.py:30 #: plugin/builtin/events/auto_create_builds.py:30 @@ -7100,1045 +7273,1062 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: 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 "InvenTree 기여자" #: 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 바코드(사람이 읽기 쉬움)" #: plugin/builtin/barcodes/inventree_barcode.py:38 msgid "Short barcodes (space optimized)" -msgstr "" +msgstr "짧은 바코드(공간 최적화)" #: plugin/builtin/barcodes/inventree_barcode.py:43 msgid "Short Barcode Prefix" -msgstr "" +msgstr "짧은 바코드 접두사" #: 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 "짧은 바코드에 사용할 접두사를 사용자 지정합니다. 여러 InvenTree 인스턴스가 있는 환경에서 유용할 수 있습니다" #: plugin/builtin/events/auto_create_builds.py:28 msgid "Auto Create Builds" -msgstr "" +msgstr "빌드 자동 생성" #: plugin/builtin/events/auto_create_builds.py:31 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 "소급 날짜 주문 발행" #: plugin/builtin/events/auto_issue_orders.py:63 msgid "Automatically issue orders that are backdated" -msgstr "" +msgstr "날짜가 소급된 주문을 자동으로 발행합니다" #: plugin/builtin/exporter/bom_exporter.py:22 msgid "Levels" -msgstr "" +msgstr "레벨" #: plugin/builtin/exporter/bom_exporter.py:24 msgid "Number of levels to export - set to zero to export all BOM levels" -msgstr "" +msgstr "내보낼 레벨 수 - 0으로 설정하면 모든 BOM 레벨을 내보냅니다" #: 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 "다중 레벨 BOM 내보내기" #: plugin/builtin/exporter/bom_exporter.py:72 msgid "Provides support for exporting multi-level BOMs" -msgstr "" +msgstr "다중 레벨 BOM 내보내기를 지원합니다" #: 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 일반 내보내기" #: plugin/builtin/exporter/inventree_exporter.py:15 msgid "Provides support for exporting data from InvenTree" -msgstr "" +msgstr "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 "" +msgstr "가격 계산에 부품 변형 재고를 포함합니다" #: plugin/builtin/exporter/stocktake_exporter.py:44 msgid "Part Stocktake Exporter" -msgstr "" +msgstr "부품 재고 조사 내보내기" #: plugin/builtin/exporter/stocktake_exporter.py:45 msgid "Exporter for part stocktake data" -msgstr "" +msgstr "부품 재고 조사 데이터 내보내기 도구" #: plugin/builtin/exporter/stocktake_exporter.py:108 msgid "Minimum Unit Cost" -msgstr "" +msgstr "최소 단가" #: plugin/builtin/exporter/stocktake_exporter.py:109 msgid "Maximum Unit Cost" -msgstr "" +msgstr "최대 단가" #: plugin/builtin/exporter/stocktake_exporter.py:110 msgid "Minimum Total Cost" -msgstr "" +msgstr "최소 총 비용" #: plugin/builtin/exporter/stocktake_exporter.py:111 msgid "Maximum Total Cost" -msgstr "" +msgstr "최대 총 비용" #: plugin/builtin/integration/core_notifications.py:23 msgid "InvenTree UI Notifications" -msgstr "" +msgstr "InvenTree UI 알림" #: plugin/builtin/integration/core_notifications.py:26 msgid "Integrated UI notification methods" -msgstr "" +msgstr "통합 UI 알림 방법" #: plugin/builtin/integration/core_notifications.py:67 msgid "InvenTree Email Notifications" -msgstr "" +msgstr "InvenTree 이메일 알림" #: plugin/builtin/integration/core_notifications.py:70 msgid "Integrated email notification methods" -msgstr "" +msgstr "통합 이메일 알림 방법" #: plugin/builtin/integration/core_notifications.py:75 msgid "Allow email notifications" -msgstr "" +msgstr "이메일 알림 허용" #: plugin/builtin/integration/core_notifications.py:76 msgid "Allow email notifications to be sent to this user" -msgstr "" +msgstr "이 사용자에게 이메일 알림을 보낼 수 있도록 허용합니다" #: plugin/builtin/integration/core_notifications.py:123 msgid "InvenTree Slack Notifications" -msgstr "" +msgstr "InvenTree Slack 알림" #: plugin/builtin/integration/core_notifications.py:126 msgid "Integrated Slack notification methods" -msgstr "" +msgstr "통합 Slack 알림 방법" #: plugin/builtin/integration/core_notifications.py:131 msgid "Slack incoming webhook URL" -msgstr "" +msgstr "Slack 수신 웹훅 URL" #: plugin/builtin/integration/core_notifications.py:132 msgid "URL that is used to send messages to a slack channel" -msgstr "" +msgstr "Slack 채널로 메시지를 보내는 데 사용되는 URL" #: plugin/builtin/integration/core_notifications.py:162 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 "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 "부품 변경 사항을 사용자에게 알립니다" #: 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 "" - -#: plugin/builtin/labels/inventree_label.py:23 -msgid "InvenTree PDF label printer" -msgstr "" +msgstr "부품 `{part.name}`에서 `{part_action}` 이벤트가 트리거되었습니다" #: plugin/builtin/labels/inventree_label.py:24 -msgid "Provides native support for printing PDF labels" -msgstr "" +msgid "InvenTree PDF label printer" +msgstr "InvenTree PDF 라벨 프린터" -#: plugin/builtin/labels/inventree_label.py:32 -#: plugin/builtin/labels/label_sheet.py:78 -msgid "Debug mode" -msgstr "" +#: plugin/builtin/labels/inventree_label.py:25 +msgid "Provides native support for printing PDF labels" +msgstr "PDF 라벨 인쇄에 대한 기본 지원을 제공합니다" #: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/label_sheet.py:78 +msgid "Debug mode" +msgstr "디버그 모드" + +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" -msgstr "" +msgstr "디버그 모드를 활성화하면 PDF 대신 원본 HTML을 반환합니다" #: 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 msgid "Page size for the label sheet" -msgstr "" +msgstr "라벨 시트의 페이지 크기" #: plugin/builtin/labels/label_sheet.py:35 msgid "Skip Labels" -msgstr "" +msgstr "라벨 건너뛰기" #: plugin/builtin/labels/label_sheet.py:36 msgid "Skip this number of labels when printing label sheets" -msgstr "" +msgstr "라벨 시트를 인쇄할 때 이 개수만큼의 라벨을 건너뜁니다" #: plugin/builtin/labels/label_sheet.py:43 msgid "Border" -msgstr "" +msgstr "테두리" #: plugin/builtin/labels/label_sheet.py:44 msgid "Print a border around each label" -msgstr "" +msgstr "각 라벨 주위에 테두리를 인쇄합니다" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" -msgstr "" +msgstr "가로" #: plugin/builtin/labels/label_sheet.py:50 msgid "Print the label sheet in landscape mode" -msgstr "" +msgstr "라벨 시트를 가로 모드로 인쇄합니다" #: plugin/builtin/labels/label_sheet.py:55 msgid "Page Margin" -msgstr "" +msgstr "페이지 여백" #: plugin/builtin/labels/label_sheet.py:56 msgid "Margin around the page in mm" -msgstr "" +msgstr "페이지 가장자리 여백(mm)" #: plugin/builtin/labels/label_sheet.py:69 msgid "InvenTree Label Sheet Printer" -msgstr "" +msgstr "InvenTree 라벨 시트 프린터" #: plugin/builtin/labels/label_sheet.py:70 msgid "Arrays multiple labels onto a single sheet" -msgstr "" +msgstr "여러 라벨을 한 장의 시트에 배열합니다" #: plugin/builtin/labels/label_sheet.py:122 msgid "Label is too large for page size" -msgstr "" +msgstr "라벨이 페이지 크기에 비해 너무 큽니다" #: plugin/builtin/labels/label_sheet.py:161 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 "'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 "'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 "'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 "" +msgstr "'TME' 역할을 하는 공급업체" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "슈퍼유저 계정만 플러그인을 관리할 수 있습니다" #: plugin/installer.py:243 msgid "Plugin installation is disabled" -msgstr "" +msgstr "플러그인 설치가 비활성화되어 있습니다" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "설치할 패키지 이름 또는 URL이 제공되지 않았습니다" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "패키지 이름 또는 URL에 잘못된 문자가 있습니다" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" -msgstr "" +msgstr "플러그인을 성공적으로 설치했습니다" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" -msgstr "" +msgstr "플러그인을 {path}에 설치했습니다" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" -msgstr "" +msgstr "레지스트리에서 플러그인을 찾을 수 없습니다" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" -msgstr "" +msgstr "플러그인이 패키지 플러그인이 아닙니다" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" -msgstr "" +msgstr "플러그인 패키지 이름을 찾을 수 없습니다" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" -msgstr "" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "스태프 사용자만 플러그인을 관리할 수 있습니다" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" -msgstr "" +msgid "Plugin uninstalling is disabled" +msgstr "플러그인 제거가 비활성화되어 있습니다" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" -msgstr "" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" +msgstr "플러그인이 현재 활성 상태이므로 제거할 수 없습니다" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "플러그인이 필수이므로 제거할 수 없습니다" + +#: plugin/installer.py:362 +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:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" -msgstr "" +msgstr "플러그인이 설치되어 있지 않습니다" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" -msgstr "" +msgstr "플러그인 설치 정보를 찾을 수 없습니다" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" -msgstr "" +msgstr "플러그인을 성공적으로 제거했습니다" #: plugin/models.py:39 msgid "Plugin Configuration" -msgstr "" +msgstr "플러그인 구성" #: plugin/models.py:40 msgid "Plugin Configurations" -msgstr "" +msgstr "플러그인 구성" #: 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 "내장 플러그인" #: plugin/models.py:192 msgid "Mandatory Plugin" -msgstr "" +msgstr "필수 플러그인" #: plugin/models.py:210 msgid "Package Plugin" -msgstr "" +msgstr "패키지 플러그인" #: plugin/models.py:301 plugin/models.py:347 msgid "Plugin" -msgstr "" +msgstr "플러그인" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" -msgstr "" - -#: plugin/registry.py:781 -#, python-brace-format -msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" -msgstr "" - -#: plugin/registry.py:784 -#, python-brace-format -msgid "Plugin requires at least version {v}" -msgstr "" +msgstr "작성자를 찾을 수 없습니다" #: plugin/registry.py:786 #, python-brace-format +msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" +msgstr "플러그인 '{p}'은(는) 현재 InvenTree 버전 {v}와 호환되지 않습니다" + +#: plugin/registry.py:789 +#, python-brace-format +msgid "Plugin requires at least version {v}" +msgstr "플러그인은 최소 버전 {v}가 필요합니다" + +#: plugin/registry.py:791 +#, python-brace-format msgid "Plugin requires at most version {v}" -msgstr "" +msgstr "플러그인은 최대 버전 {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 "InvenTree 인터페이스에서 구매 주문(PO) 기능을 활성화합니다" #: 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 "외부 API에 접근하기 위한 키" #: plugin/samples/integration/sample.py:83 msgid "Numerical" -msgstr "" +msgstr "숫자" #: plugin/samples/integration/sample.py:84 msgid "A numerical setting" -msgstr "" +msgstr "숫자 설정" #: plugin/samples/integration/sample.py:90 msgid "Choice Setting" -msgstr "" +msgstr "선택 설정" #: 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" -msgstr "" +msgstr "InvenTree 기여자" #: 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 "부품 보기용 사용자 정의 패널을 활성화합니다" #: 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 "구매 주문 보기용 사용자 정의 패널을 활성화합니다" #: plugin/samples/integration/user_interface_sample.py:39 msgid "Enable Broken Panels" -msgstr "" +msgstr "손상된 패널 활성화" #: plugin/samples/integration/user_interface_sample.py:40 msgid "Enable broken panels for testing" -msgstr "" +msgstr "테스트를 위해 손상된 패널을 활성화합니다" #: plugin/samples/integration/user_interface_sample.py:45 msgid "Enable Dynamic Panel" -msgstr "" +msgstr "동적 패널 활성화" #: plugin/samples/integration/user_interface_sample.py:46 msgid "Enable dynamic panels for testing" -msgstr "" +msgstr "테스트를 위해 동적 패널을 활성화합니다" #: plugin/samples/integration/user_interface_sample.py:114 msgid "Part Panel" -msgstr "" +msgstr "부품 패널" #: plugin/samples/integration/user_interface_sample.py:149 msgid "Broken Dashboard Item" -msgstr "" +msgstr "손상된 대시보드 항목" #: plugin/samples/integration/user_interface_sample.py:151 msgid "This is a broken dashboard item - it will not render!" -msgstr "" +msgstr "이것은 손상된 대시보드 항목입니다. 렌더링되지 않습니다!" #: 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 "이것은 샘플 대시보드 항목입니다. 단순한 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 "이것은 관리자 전용 대시보드 항목입니다." #: 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 "플러그인 패키지 이름입니다. 버전 표기를 포함할 수도 있습니다" #: 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 "플러그인 버전 지정자입니다. 최신 버전이면 비워 두세요." #: 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 "이 플러그인을 현재 인스턴스에 지금 설치합니다. 인스턴스는 유지보수 모드로 전환됩니다." #: plugin/serializers.py:150 msgid "Installation not confirmed" -msgstr "" +msgstr "설치가 확인되지 않았습니다" #: plugin/serializers.py:152 msgid "Either packagename or URL must be provided" -msgstr "" +msgstr "패키지 이름 또는 URL 중 하나는 제공되어야 합니다" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" -msgstr "" +msgstr "전체 다시 로드" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" -msgstr "" +msgstr "플러그인 레지스트리를 전체 다시 로드합니다" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" -msgstr "" +msgstr "강제 다시 로드" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" -msgstr "" +msgstr "이미 로드되어 있더라도 플러그인 레지스트리를 강제로 다시 로드합니다" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" -msgstr "" +msgstr "플러그인 수집" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" -msgstr "" +msgstr "플러그인을 수집하여 레지스트리에 추가합니다" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" -msgstr "" +msgstr "플러그인 활성화" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" -msgstr "" +msgstr "이 플러그인을 활성화합니다" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" -msgstr "" +msgstr "필수 플러그인은 비활성화할 수 없습니다" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" -msgstr "" +msgstr "구성 삭제" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" -msgstr "" +msgstr "데이터베이스에서 플러그인 구성을 삭제합니다" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" -msgstr "" +msgstr "이 설정이 적용될 사용자" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" -msgstr "" +msgstr "항목" #: report/api.py:115 msgid "Plugin not found" -msgstr "" +msgstr "플러그인을 찾을 수 없습니다" #: report/api.py:117 msgid "Plugin does not support label printing" -msgstr "" +msgstr "플러그인이 라벨 인쇄를 지원하지 않습니다" #: report/api.py:165 msgid "Invalid label dimensions" -msgstr "" +msgstr "잘못된 라벨 크기입니다" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" -msgstr "" +msgstr "템플릿에 유효한 항목이 제공되지 않았습니다" #: report/helpers.py:43 msgid "A4" -msgstr "" +msgstr "A4" #: report/helpers.py:44 msgid "A3" -msgstr "" +msgstr "A3" #: report/helpers.py:45 msgid "Legal" -msgstr "" +msgstr "Legal" #: report/helpers.py:46 msgid "Letter" -msgstr "" +msgstr "Letter" #: report/models.py:128 msgid "Template file with this name already exists" -msgstr "" +msgstr "이 이름의 템플릿 파일이 이미 존재합니다" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" -msgstr "" +msgstr "템플릿 이름" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" -msgstr "" +msgstr "템플릿 설명" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" -msgstr "" +msgstr "리비전 번호(자동 증가)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" -msgstr "" +msgstr "인쇄 시 모델에 첨부" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" -msgstr "" +msgstr "인쇄 시 보고서 출력물을 연결된 모델 인스턴스에 첨부파일로 저장합니다" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" -msgstr "" - -#: report/models.py:282 -msgid "Pattern for generating filenames" -msgstr "" +msgstr "파일명 패턴" #: report/models.py:287 +msgid "Pattern for generating filenames" +msgstr "파일명을 생성하기 위한 패턴" + +#: report/models.py:292 msgid "Template is enabled" -msgstr "" +msgstr "템플릿이 활성화됨" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" -msgstr "" +msgstr "템플릿 대상 모델 유형" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" -msgstr "" +msgstr "필터" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" -msgstr "" +msgstr "템플릿 쿼리 필터(쉼표로 구분된 key=value 쌍 목록)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" -msgstr "" +msgstr "템플릿 파일" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" -msgstr "" - -#: report/models.py:388 -msgid "Render report in landscape orientation" -msgstr "" +msgstr "PDF 보고서 페이지 크기" #: report/models.py:393 +msgid "Render report in landscape orientation" +msgstr "보고서를 가로 방향으로 렌더링" + +#: report/models.py:398 msgid "Merge" -msgstr "" +msgstr "병합" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" -msgstr "" +msgstr "선택한 항목에 대해 단일 보고서를 렌더링합니다" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" -msgstr "" +msgstr "템플릿 {self.name}에서 생성된 보고서" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" -msgstr "" +msgstr "템플릿 구문 오류" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" -msgstr "" +msgstr "보고서 렌더링 오류" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" -msgstr "" +msgstr "보고서 생성 오류" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" -msgstr "" +msgstr "보고서 출력 병합 오류" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" -msgstr "" +msgstr "너비 [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" -msgstr "" +msgstr "라벨 너비(mm)" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" -msgstr "" +msgstr "높이 [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" -msgstr "" +msgstr "라벨 높이(mm)" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" -msgstr "" +msgstr "라벨 인쇄 오류" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" -msgstr "" +msgstr "스니펫" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" -msgstr "" +msgstr "보고서 스니펫 파일" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" -msgstr "" +msgstr "스니펫 파일 설명" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" -msgstr "" +msgstr "자산" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" -msgstr "" +msgstr "보고서 자산 파일" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" -msgstr "" +msgstr "자산 파일 설명" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "보고서 템플릿을 저장하려면 사용자 인증이 필요합니다" + +#: report/serializers.py:118 msgid "Select report template" -msgstr "" +msgstr "보고서 템플릿 선택" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" -msgstr "" +msgstr "보고서에 포함할 항목의 기본 키 목록" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" -msgstr "" +msgstr "라벨 템플릿 선택" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" -msgstr "" +msgstr "인쇄 플러그인" -#: report/serializers.py:145 +#: report/serializers.py:168 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" -msgstr "" +msgstr "필요한 자재" #: report/templates/report/inventree_build_order_report.html:98 #: report/templates/report/inventree_purchase_order_report.html:47 @@ -8149,1101 +8339,1121 @@ msgstr "" #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 msgid "Part image" -msgstr "" +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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 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:630 +#: stock/serializers.py:655 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:169 -msgid "Asset file does not exist" -msgstr "" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "잘못된 미디어 파일 경로" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "잘못된 정적 파일 경로" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "자산 파일을 찾을 수 없습니다" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" -msgstr "" +msgstr "이미지 파일을 찾을 수 없습니다" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "이미지 파일이 지정되지 않았습니다" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" -msgstr "" +msgstr "part_image 태그에는 Part 인스턴스가 필요합니다" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" -msgstr "" +msgstr "company_image 태그에는 Company 인스턴스가 필요합니다" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" -msgstr "" +msgstr "위치 깊이로 필터" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" -msgstr "" +msgstr "최상위 위치로 필터" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" -msgstr "" +msgstr "필터 결과에 하위 위치를 포함합니다" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" -msgstr "" +msgstr "상위 위치" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" -msgstr "" +msgstr "상위 위치로 필터" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" -msgstr "" +msgstr "부품명(대소문자 구분 없음)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" -msgstr "" +msgstr "부품명 포함(대소문자 구분 없음)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" -msgstr "" +msgstr "부품명(정규식)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" -msgstr "" +msgstr "부품 IPN(대소문자 구분 없음)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" -msgstr "" +msgstr "부품 IPN 포함(대소문자 구분 없음)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" -msgstr "" +msgstr "부품 IPN(정규식)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" -msgstr "" +msgstr "최소 재고" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" -msgstr "" +msgstr "최대 재고" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" -msgstr "" +msgstr "상태 코드" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" -msgstr "" +msgstr "외부 위치" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" -msgstr "" +msgstr "작업 지시서에서 소비됨" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" -msgstr "" +msgstr "다른 재고 품목에 설치됨" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" -msgstr "" +msgstr "부품 트리" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" -msgstr "" +msgstr "업데이트 날짜 이전" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" -msgstr "" +msgstr "업데이트 날짜 이후" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" -msgstr "" +msgstr "재고조사 날짜 이전" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" -msgstr "" +msgstr "재고조사 날짜 이후" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" -msgstr "" +msgstr "유효기간 날짜 이전" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" -msgstr "" +msgstr "유효기간 날짜 이후" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" -msgstr "" +msgstr "장기 재고" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" +msgstr "제외할 재고 품목 PK를 제공하면 해당 품목과 모든 하위 항목을 제외합니다" + +#: stock/api.py:980 +msgid "Cascade Locations" +msgstr "위치 계단식 적용" #: stock/api.py:981 -msgid "Cascade Locations" -msgstr "" - -#: stock/api.py:982 msgid "If true, include items in child locations of the given location" -msgstr "" +msgstr "true이면 지정한 위치의 하위 위치에 있는 항목을 포함합니다" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" -msgstr "" +msgstr "숫자 Location ID 또는 'null' 리터럴로 필터" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" -msgstr "" +msgstr "수량이 필요합니다" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" -msgstr "" +msgstr "유효한 부품을 제공해야 합니다" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" -msgstr "" +msgstr "지정한 공급업체 부품이 존재하지 않습니다" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" -msgstr "" +msgstr "공급업체 부품에 포장 단위가 정의되어 있지만 use_pack_size 플래그가 설정되지 않았습니다" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" -msgstr "" +msgstr "추적 불가능한 부품에는 시리얼 번호를 제공할 수 없습니다" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" -msgstr "" +msgstr "설치된 항목 포함" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" -msgstr "" +msgstr "true이면 지정한 재고 품목 아래에 설치된 항목의 테스트 결과를 포함합니다" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" -msgstr "" +msgstr "숫자 재고 품목 ID로 필터" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" -msgstr "" +msgstr "ID가 {id}인 재고 품목이 존재하지 않습니다" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" -msgstr "" +msgstr "부품 변형 포함" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" -msgstr "" +msgstr "날짜 이후" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" -msgstr "" +msgstr "날짜 이전" #: stock/models.py:73 msgid "Stock Location type" -msgstr "" +msgstr "재고 위치 유형" #: stock/models.py:74 msgid "Stock Location types" -msgstr "" +msgstr "재고 위치 유형" #: stock/models.py:100 msgid "Default icon for all locations that have no icon set (optional)" -msgstr "" +msgstr "아이콘이 설정되지 않은 모든 위치에 대한 기본 아이콘(선택)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" -msgstr "" +msgstr "재고 위치" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" -msgstr "" +msgstr "재고 위치" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" -msgstr "" +msgstr "소유자" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" -msgstr "" +msgstr "소유자 선택" #: stock/models.py:206 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." -msgstr "" +msgstr "재고 품목은 구조적 재고 위치에 직접 배치할 수 없으며, 하위 위치에 배치할 수 있습니다." -#: stock/models.py:213 users/models.py:497 +#: stock/models.py:213 users/models.py:495 msgid "External" -msgstr "" +msgstr "외부" #: stock/models.py:214 msgid "This is an external stock location" -msgstr "" +msgstr "외부 재고 위치입니다" #: stock/models.py:220 msgid "Location type" -msgstr "" +msgstr "위치 유형" #: stock/models.py:224 msgid "Stock location type of this location" -msgstr "" +msgstr "이 위치의 재고 위치 유형" #: stock/models.py:296 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:583 +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" -msgstr "" +msgstr "{field}이(가) 존재하지 않습니다" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" -msgstr "" +msgstr "부품을 지정해야 합니다" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" +msgstr "재고 품목은 구조적 재고 위치에 배치할 수 없습니다!" + +#: stock/models.py:945 +msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:962 stock/serializers.py:469 msgid "Stock item cannot be created for virtual parts" -msgstr "" +msgstr "가상 부품에 대해 재고 품목을 생성할 수 없습니다" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" -msgstr "" +msgstr "시리얼 번호가 있는 품목의 수량은 1이어야 합니다" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" -msgstr "" +msgstr "수량이 1보다 크면 시리얼 번호를 설정할 수 없습니다" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" -msgstr "" +msgstr "항목은 자기 자신에 속할 수 없습니다" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" -msgstr "" - -#: stock/models.py:1006 -msgid "Build reference does not point to the same part object" -msgstr "" - -#: stock/models.py:1020 -msgid "Parent Stock Item" -msgstr "" +msgstr "is_building=True인 경우 항목에는 제조 참조가 있어야 합니다" #: 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:1042 -msgid "Select a matching supplier part for this stock item" -msgstr "" - -#: stock/models.py:1054 -msgid "Where is this stock item located?" -msgstr "" - -#: stock/models.py:1062 stock/serializers.py:1638 -msgid "Packaging this stock item is stored in" -msgstr "" +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 "" +msgstr "설치 위치" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" -msgstr "" +msgstr "이 항목이 다른 항목에 설치되어 있습니까?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" -msgstr "" +msgstr "이 항목의 시리얼 번호" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" -msgstr "" +msgstr "이 재고 품목의 배치 코드" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" -msgstr "" - -#: stock/models.py:1124 -msgid "Source Build" -msgstr "" - -#: stock/models.py:1127 -msgid "Build for this stock item" -msgstr "" - -#: stock/models.py:1134 -msgid "Consumed By" -msgstr "" - -#: stock/models.py:1137 -msgid "Build order which consumed this stock item" -msgstr "" - -#: stock/models.py:1146 -msgid "Source Purchase Order" -msgstr "" +msgstr "재고 수량" #: stock/models.py:1150 +msgid "Source Build" +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:1176 msgid "Purchase order for this stock item" -msgstr "" +msgstr "이 재고 품목의 구매 주문" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" -msgstr "" +msgstr "대상 판매 주문" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" -msgstr "" +msgstr "재고 품목의 유효기간입니다. 이 날짜 이후 재고는 만료로 간주됩니다" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" -msgstr "" +msgstr "소진 시 삭제" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" -msgstr "" +msgstr "재고가 소진되면 이 재고 품목을 삭제합니다" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" -msgstr "" +msgstr "구매 시점의 단위 구매 가격" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" -msgstr "" +msgstr "부품으로 변환됨" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" -msgstr "" +msgstr "수량이 사용 가능한 재고를 초과합니다" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" -msgstr "" +msgstr "부품이 추적으로 설정되어 있지 않습니다" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" -msgstr "" +msgstr "수량은 정수여야 합니다" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" -msgstr "" +msgstr "수량은 사용 가능한 재고 수량({self.quantity})을 초과할 수 없습니다" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" -msgstr "" +msgstr "시리얼 번호는 목록으로 제공되어야 합니다" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" -msgstr "" +msgstr "수량이 시리얼 번호와 일치하지 않습니다" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" -msgstr "" +msgstr "구조적 위치에 재고를 할당할 수 없습니다" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" -msgstr "" +msgstr "테스트 템플릿이 존재하지 않습니다" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" -msgstr "" +msgstr "재고 품목이 판매 주문에 할당되었습니다" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" -msgstr "" +msgstr "재고 품목이 다른 품목에 설치되어 있습니다" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" -msgstr "" +msgstr "재고 품목에 다른 품목이 포함되어 있습니다" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" -msgstr "" +msgstr "재고 품목이 고객에게 할당되었습니다" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" -msgstr "" +msgstr "재고 품목이 현재 생산 중입니다" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" -msgstr "" +msgstr "시리얼 추적 재고는 병합할 수 없습니다" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" -msgstr "" +msgstr "중복 재고 품목" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" -msgstr "" +msgstr "재고 품목은 동일한 부품을 참조해야 합니다" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" -msgstr "" +msgstr "재고 항목은 동일한 공급업체 부품을 참조해야 합니다" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" -msgstr "" +msgstr "재고 상태 코드는 일치해야 합니다" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" -msgstr "" +msgstr "재고에 없으므로 재고 항목을 이동할 수 없습니다" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" -msgstr "" +msgstr "재고 항목 추적" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" -msgstr "" +msgstr "항목 메모" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" -msgstr "" +msgstr "재고 항목 테스트 결과" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" -msgstr "" +msgstr "이 테스트에는 값을 제공해야 합니다" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" -msgstr "" +msgstr "이 테스트에는 첨부 파일을 업로드해야 합니다" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" -msgstr "" +msgstr "이 테스트의 값이 올바르지 않습니다" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" -msgstr "" +msgstr "테스트 결과" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" -msgstr "" +msgstr "테스트 출력 값" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" -msgstr "" +msgstr "테스트 결과 첨부 파일" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" -msgstr "" +msgstr "테스트 메모" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" -msgstr "" +msgstr "테스트 스테이션" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" -msgstr "" +msgstr "테스트가 수행된 테스트 스테이션의 식별자" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" -msgstr "" +msgstr "시작됨" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" -msgstr "" +msgstr "테스트 시작 시각" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" -msgstr "" +msgstr "완료됨" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" -msgstr "" +msgstr "테스트 종료 시각" #: stock/serializers.py:85 msgid "Generated batch code" -msgstr "" +msgstr "생성된 배치 코드" #: stock/serializers.py:94 msgid "Select build order" -msgstr "" +msgstr "제조 주문 선택" #: stock/serializers.py:103 msgid "Select stock item to generate batch code for" -msgstr "" +msgstr "배치 코드를 생성할 재고 항목을 선택하세요" #: stock/serializers.py:112 msgid "Select location to generate batch code for" -msgstr "" +msgstr "배치 코드를 생성할 위치를 선택하세요" #: stock/serializers.py:121 msgid "Select part to generate batch code for" -msgstr "" +msgstr "배치 코드를 생성할 부품을 선택하세요" #: stock/serializers.py:130 msgid "Select purchase order" -msgstr "" +msgstr "구매 주문 선택" #: stock/serializers.py:137 msgid "Enter quantity for batch code" -msgstr "" +msgstr "배치 코드 수량을 입력하세요" #: stock/serializers.py:163 msgid "Generated serial number" -msgstr "" +msgstr "생성된 일련 번호" #: stock/serializers.py:173 msgid "Select part to generate serial number for" -msgstr "" +msgstr "일련 번호를 생성할 부품을 선택하세요" #: stock/serializers.py:181 msgid "Quantity of serial numbers to generate" -msgstr "" +msgstr "생성할 일련 번호 수량" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" -msgstr "" +msgstr "이 결과의 테스트 템플릿" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" -msgstr "" +msgstr "이 부품에 일치하는 테스트를 찾을 수 없습니다" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" -msgstr "" +msgstr "템플릿 ID 또는 테스트 이름을 제공해야 합니다" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" -msgstr "" +msgstr "테스트 종료 시각은 테스트 시작 시각보다 빠를 수 없습니다" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" -msgstr "" +msgstr "상위 항목" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" -msgstr "" +msgstr "상위 재고 항목" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" -msgstr "" +msgstr "추가 시 포장 단위 사용: 입력한 수량은 포장 개수입니다" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" -msgstr "" +msgstr "포장 단위 사용" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" -msgstr "" +msgstr "새 항목의 일련 번호를 입력하세요" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" -msgstr "" +msgstr "공급업체 부품 번호" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" -msgstr "" +msgstr "만료됨" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" -msgstr "" +msgstr "하위 항목" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" -msgstr "" +msgstr "추적 항목" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" -msgstr "" +msgstr "이 재고 항목의 구매 가격(단위 또는 포장 기준)" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" -msgstr "" +msgstr "일련 번호를 부여할 재고 항목 수를 입력하세요" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" -msgstr "" +msgstr "재고 항목이 제공되지 않았습니다" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" -msgstr "" +msgstr "수량은 사용 가능한 재고 수량({q})을(를) 초과할 수 없습니다" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" -msgstr "" +msgstr "대상 재고 위치" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" -msgstr "" +msgstr "이 부품에는 일련 번호를 할당할 수 없습니다" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" -msgstr "" +msgstr "일련 번호가 이미 존재합니다" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" -msgstr "" +msgstr "설치할 재고 항목을 선택하세요" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" -msgstr "" +msgstr "설치 수량" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" -msgstr "" +msgstr "설치할 항목 수량을 입력하세요" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" -msgstr "" +msgstr "거래 메모 추가(선택 사항)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" -msgstr "" +msgstr "설치 수량은 최소 1이어야 합니다" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" -msgstr "" +msgstr "재고 항목을 사용할 수 없습니다" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" -msgstr "" +msgstr "선택한 부품이 BOM(자재 명세서)에 없습니다" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" -msgstr "" +msgstr "설치 수량은 사용 가능한 수량을 초과할 수 없습니다" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" -msgstr "" +msgstr "미설치 항목의 대상 위치" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" -msgstr "" +msgstr "재고 항목을 변환할 부품을 선택하세요" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" -msgstr "" +msgstr "선택한 부품은 변환에 사용할 수 없는 옵션입니다" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" +msgstr "공급업체 부품이 할당된 재고 항목은 변환할 수 없습니다" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" -msgstr "" +msgstr "재고 항목 상태 코드" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" -msgstr "" +msgstr "상태를 변경할 재고 항목을 선택하세요" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" -msgstr "" +msgstr "선택된 재고 항목이 없습니다" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" -msgstr "" +msgstr "하위 위치" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" -msgstr "" +msgstr "상위 재고 위치" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" -msgstr "" +msgstr "부품은 판매 가능해야 합니다" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" -msgstr "" +msgstr "항목이 판매 주문에 할당되어 있습니다" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" -msgstr "" +msgstr "항목이 제조 주문에 할당되어 있습니다" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" -msgstr "" +msgstr "재고 항목을 할당할 고객" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" -msgstr "" +msgstr "선택한 회사는 고객이 아닙니다" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" -msgstr "" +msgstr "재고 할당 메모" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" -msgstr "" +msgstr "재고 항목 목록을 제공해야 합니다" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" -msgstr "" +msgstr "재고 병합 메모" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" -msgstr "" +msgstr "공급업체 불일치 허용" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" -msgstr "" +msgstr "공급업체 부품이 다른 재고 항목의 병합을 허용합니다" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" -msgstr "" +msgstr "상태 불일치 허용" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" -msgstr "" +msgstr "상태 코드가 다른 재고 항목의 병합을 허용합니다" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" -msgstr "" +msgstr "최소 두 개의 재고 항목을 제공해야 합니다" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" -msgstr "" +msgstr "변경 없음" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" -msgstr "" +msgstr "재고 항목 기본 키 값" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" -msgstr "" +msgstr "재고 항목이 재고에 없습니다" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" -msgstr "" +msgstr "재고 항목이 이미 재고에 있습니다" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" -msgstr "" +msgstr "수량은 음수일 수 없습니다" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1826 -msgid "Merge into existing stock" -msgstr "" - -#: stock/serializers.py:1827 -msgid "Merge returned items into existing stock items if possible" -msgstr "" +msgstr "재고 거래 메모" #: stock/serializers.py:1870 -msgid "Next Serial Number" -msgstr "" +msgid "Merge into existing stock" +msgstr "기존 재고로 병합" -#: stock/serializers.py:1876 +#: stock/serializers.py:1871 +msgid "Merge returned items into existing stock items if possible" +msgstr "가능하면 반품된 항목을 기존 재고 항목에 병합합니다" + +#: stock/serializers.py:1914 +msgid "Next Serial Number" +msgstr "다음 일련 번호" + +#: stock/serializers.py:1920 msgid "Previous Serial Number" -msgstr "" +msgstr "이전 일련 번호" #: stock/status_codes.py:11 msgid "OK" -msgstr "" +msgstr "정상" #: stock/status_codes.py:12 msgid "Attention needed" -msgstr "" +msgstr "주의 필요" #: stock/status_codes.py:13 msgid "Damaged" -msgstr "" +msgstr "손상됨" #: stock/status_codes.py:14 msgid "Destroyed" -msgstr "" +msgstr "폐기됨" #: stock/status_codes.py:15 msgid "Rejected" -msgstr "" +msgstr "거부됨" #: stock/status_codes.py:19 msgid "Quarantined" -msgstr "" +msgstr "격리됨" #: stock/status_codes.py:44 msgid "Legacy stock tracking entry" -msgstr "" +msgstr "레거시 재고 추적 항목" #: 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 "재고 실사됨" #: 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 "재고 항목 병합됨" #: stock/status_codes.py:79 msgid "Converted to variant" -msgstr "" +msgstr "변형(Variant)으로 변환됨" #: stock/status_codes.py:82 msgid "Build order output created" -msgstr "" +msgstr "제조 주문 출력 생성됨" #: stock/status_codes.py:83 msgid "Build order output completed" -msgstr "" +msgstr "제조 주문 출력 완료됨" #: stock/status_codes.py:84 msgid "Build order output rejected" -msgstr "" +msgstr "제조 주문 출력 거부됨" #: stock/status_codes.py:85 msgid "Consumed by build order" -msgstr "" +msgstr "제조 주문에서 소모됨" #: stock/status_codes.py:88 msgid "Shipped against Sales Order" -msgstr "" +msgstr "판매 주문으로 출하됨" #: stock/status_codes.py:91 msgid "Received against Purchase Order" -msgstr "" +msgstr "구매 주문으로 입고됨" #: stock/status_codes.py:94 msgid "Returned against Return Order" -msgstr "" +msgstr "반품 주문으로 반품됨" #: stock/status_codes.py:97 msgid "Sent to customer" -msgstr "" +msgstr "고객에게 발송됨" #: stock/status_codes.py:98 msgid "Returned from customer" -msgstr "" +msgstr "고객으로부터 반품됨" #: templates/403.html:6 templates/403.html:10 templates/403_csrf.html:7 msgid "Permission Denied" -msgstr "" +msgstr "권한이 없습니다" #: 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 "인증 실패" #: 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 "요청한 페이지가 존재하지 않습니다" #: 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 서버에서 내부 오류가 발생했습니다" #: templates/500.html:12 msgid "Refer to the error log in the admin interface for further details" -msgstr "" +msgstr "자세한 내용은 관리자 인터페이스의 오류 로그를 확인하세요" #: templates/503.html:11 templates/503.html:15 msgid "Site is in Maintenance" -msgstr "" +msgstr "사이트 점검 중" #: templates/503.html:17 msgid "The site is currently in maintenance and should be up again soon!" -msgstr "" +msgstr "현재 사이트가 점검 중이며 곧 다시 이용할 수 있습니다!" #: 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 "자세한 내용은 시스템 관리자에게 문의하세요" #: 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 "주의가 필요한 대기 중인 데이터베이스 마이그레이션이 있습니다" #: 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 서버에서 구성 오류가 발생했습니다" #: templates/email/build_order_completed.html:9 #: templates/email/canceled_order_assigned.html:9 @@ -9255,341 +9465,361 @@ 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 - %(part)s %(quantity)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 "이 부품에 대한 알림을 구독하고 있어 이 이메일을 받고 있습니다 " #: 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 "이 부품 또는 이 부품이 속한 카테고리에 대한 알림을 구독하고 있어 이 이메일을 받고 있습니다 " #: templates/email/stale_stock_notification.html:10 msgid "The following stock items are approaching their expiry dates:" -msgstr "" +msgstr "다음 재고 항목의 유효기간이 곧 만료됩니다:" #: 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 "이 부품들에 대한 알림을 구독하고 있어 이 이메일을 받고 있습니다" #: 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 msgid "Personal info" -msgstr "" +msgstr "개인 정보" #: users/admin.py:139 msgid "Permissions" -msgstr "" +msgstr "권한" #: users/admin.py:142 msgid "Important dates" -msgstr "" +msgstr "중요 날짜" #: users/authentication.py:30 users/models.py:151 msgid "Token has been revoked" -msgstr "" +msgstr "토큰이 취소되었습니다" #: users/authentication.py:33 msgid "Token has expired" -msgstr "" +msgstr "토큰이 만료되었습니다" #: users/models.py:94 msgid "API Token" -msgstr "" +msgstr "API 토큰" #: users/models.py:95 msgid "API Tokens" -msgstr "" +msgstr "API 토큰" #: users/models.py:131 msgid "Token Name" -msgstr "" +msgstr "토큰 이름" #: users/models.py:132 msgid "Custom token name" -msgstr "" +msgstr "사용자 지정 토큰 이름" #: users/models.py:138 msgid "Token expiry date" -msgstr "" +msgstr "토큰 만료일" #: users/models.py:146 msgid "Last Seen" -msgstr "" +msgstr "마지막 사용" #: users/models.py:147 msgid "Last time the token was used" -msgstr "" +msgstr "토큰이 마지막으로 사용된 시간" #: users/models.py:151 msgid "Revoked" -msgstr "" +msgstr "취소됨" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" -msgstr "" +msgstr "권한 세트" -#: users/models.py:242 +#: users/models.py:240 msgid "View" -msgstr "" +msgstr "보기" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" -msgstr "" +msgstr "항목을 볼 권한" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" -msgstr "" +msgstr "추가" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" -msgstr "" +msgstr "항목을 추가할 권한" + +#: users/models.py:248 +msgid "Change" +msgstr "변경" #: users/models.py:250 -msgid "Change" -msgstr "" - -#: users/models.py:252 msgid "Permissions to edit items" -msgstr "" +msgstr "항목을 수정할 권한" + +#: users/models.py:254 +msgid "Delete" +msgstr "삭제" #: users/models.py:256 -msgid "Delete" -msgstr "" - -#: users/models.py:258 msgid "Permission to delete items" -msgstr "" +msgstr "항목을 삭제할 권한" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" -msgstr "" +msgstr "봇" + +#: users/models.py:494 +msgid "Internal" +msgstr "내부" #: users/models.py:496 -msgid "Internal" -msgstr "" - -#: users/models.py:498 msgid "Guest" -msgstr "" +msgstr "게스트" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" -msgstr "" +msgstr "언어" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" -msgstr "" +msgstr "사용자의 선호 언어" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" -msgstr "" +msgstr "테마" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" -msgstr "" +msgstr "웹 UI 설정(JSON) - 수동으로 편집하지 마세요!" + +#: users/models.py:517 +msgid "Widgets" +msgstr "위젯" #: users/models.py:519 -msgid "Widgets" -msgstr "" - -#: users/models.py:521 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" -msgstr "" +msgstr "대시보드 위젯 설정(JSON) - 수동으로 편집하지 마세요!" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" -msgstr "" +msgstr "표시 이름" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" -msgstr "" +msgstr "사용자가 선택한 표시 이름" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" -msgstr "" +msgstr "직책" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" -msgstr "" +msgstr "주요 직함 또는 직책" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" -msgstr "" +msgstr "사용자 상태 메시지" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" -msgstr "" +msgstr "사용자 위치 정보" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" -msgstr "" +msgstr "사용자가 시스템을 사용 중입니다" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" -msgstr "" +msgstr "사용자가 선호하는 연락처 정보" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" -msgstr "" +msgstr "사용자 유형" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" -msgstr "" +msgstr "어떤 유형의 사용자입니까?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" -msgstr "" +msgstr "조직" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" -msgstr "" +msgstr "사용자의 기본 조직/소속" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" -msgstr "" +msgstr "기본 그룹" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" -msgstr "" +msgstr "사용자의 기본 그룹" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" -msgstr "" +msgstr "관리자" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "구매 주문" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "판매 주문" + +#: users/ruleset.py:36 msgid "Return Orders" -msgstr "" +msgstr "반품 주문" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" -msgstr "" +msgstr "사용자 이름" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" -msgstr "" +msgstr "이름" + +#: users/serializers.py:189 +msgid "First name of the user" +msgstr "사용자의 이름" #: users/serializers.py:193 -msgid "First name of the user" -msgstr "" - -#: users/serializers.py:197 msgid "Last Name" -msgstr "" +msgstr "성" + +#: users/serializers.py:193 +msgid "Last name of the user" +msgstr "사용자의 성" #: users/serializers.py:197 -msgid "Last name of the user" -msgstr "" - -#: users/serializers.py:201 msgid "Email address of the user" -msgstr "" +msgstr "사용자의 이메일 주소" -#: users/serializers.py:309 -msgid "Staff" -msgstr "" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "사용자가 인증되어야 합니다" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "슈퍼유저만 다른 사용자의 토큰을 만들 수 있습니다" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "관리자" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "이 사용자에게 관리자 권한이 있습니까" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" -msgstr "" +msgstr "슈퍼유저" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" -msgstr "" +msgstr "이 사용자는 슈퍼유저입니까" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" -msgstr "" +msgstr "이 사용자 계정이 활성 상태입니까" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" -msgstr "" +msgstr "슈퍼유저만 이 필드를 조정할 수 있습니다" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" -msgstr "" +msgstr "비밀번호" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" -msgstr "" +msgstr "사용자의 비밀번호" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" -msgstr "" +msgstr "경고 무시" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" -msgstr "" +msgstr "비밀번호 규칙에 대한 경고를 무시합니다" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "스태프" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "이 사용자에게 스태프 권한이 있습니까" + +#: users/serializers.py:468 msgid "You do not have permission to create users" -msgstr "" +msgstr "사용자를 생성할 권한이 없습니다" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." -msgstr "" +msgstr "계정이 생성되었습니다." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" -msgstr "" +msgstr "로그인하려면 비밀번호 재설정 기능을 사용하세요" -#: users/serializers.py:452 +#: users/serializers.py:497 msgid "Welcome to InvenTree" -msgstr "" +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 cdd58ce699..fac3f7a446 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Lithuanian\n" "Language: lt_LT\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API galinis taškas nerastas" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Masiniam veiksmui turi būti pateiktas elementų arba filtrų sąrašas" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Elementai turi būti pateikti kaip sąrašas" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Pateiktas neteisingas elementų sąrašas" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "\"Filtrai turi būti pateikti kaip žodynas" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Pateikti neteisingi filtrai" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Filtras „all“ gali būti naudojamas tik su reikšme „true“" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Nė vienas elementas neatitinka pateiktų kriterijų" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Vartotojas neturi teisių peržiūrėti šio modelio" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Nepavyko konvertuoti {original} į {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Pateiktas neteisingas kiekis" @@ -112,13 +105,13 @@ msgstr "Įveskite datą" msgid "Invalid decimal value" msgstr "Neteisinga dešimtainė reikšmė" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Pastabos" @@ -131,75 +124,91 @@ msgstr "Reikšmė „{name}“ neatitinka šablono formato" msgid "Provided value does not match required pattern: " msgstr "Pateikta reikšmė neatitinka reikalaujamo šablono: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Negalima iš karto susieti daugiau nei 1000 elementų" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Nepateiktas serijos numeris" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Pasikartojantis serijinis numeris" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Neteisinga grupė: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Serijos numerių nerasta" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Pašalinkite HTML žymes iš šios reikšmės" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Duomenyse yra draudžiamo „markdown“ turinio" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Ryšio klaida" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serveris grąžino netinkamą būsenos kodą" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Įvyko išimtis" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serveris grąžino neteisingą „Content-Length“ reikšmę" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Paveikslėlio dydis per didelis" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Paveikslėlio atsisiuntimas viršijo maksimalų leistiną dydį" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Nutolęs serveris grąžino tuščią atsakymą" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Nurodytas URL nėra tinkamas paveikslėlio failas" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "El. paštas" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Prieš atliekant bet kokius veiksmus, privalote įjungti dviejų veiksnių autentifikavimą." @@ -255,133 +264,108 @@ msgstr "Nuoroda turi atitikti reikalaujamą šabloną" msgid "Reference number is too large" msgstr "Nuorodos numeris per didelis" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Neteisingas pasirinkimas" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Pavadinimas" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Aprašymas" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Aprašymas (neprivalomas)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Kelias" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 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:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Pastabos su „Markdown“ (neprivalomas)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Brūkšninio kodo duomenys" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Trečiosios šalies brūkšninio kodo duomenys" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Brūkšninio kodo maiša" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unikali brūkšninio kodo duomenų maiša\"" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Rastas esamas brūkšninis kodas" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Užduoties klaida" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Foninė užduotis '{f}' nepavyko po {n} bandymų" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverio klaida" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Serveris užfiksavo klaidą." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Turi būti teisingas skaičius" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valiuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Pasirinkite valiutą iš galimų variantų" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Neteisinga reikšmė" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Nutolęs paveikslėlis" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Nutolusio paveikslėlio failo URL" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Paveikslėlių atsisiuntimas iš nutolusio URL neįjungtas" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Nepavyko atsisiųsti paveikslėlio iš nutolusio URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kinų (supaprastinta)" msgid "Chinese (Traditional)" msgstr "Kinų (tradicinė)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Neteisingas fizinis vienetas" msgid "Not a valid currency code" msgstr "Netinkamas valiutos kodas" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Užsakymo būsena" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Pirminė gamyba" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Įtraukti variantus" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Įtraukti variantus" msgid "Part" msgstr "Detalė" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategorija" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Ankstesnė gamyba" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Priskirta man" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Priskirta" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Sukurta prieš" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Sukurta po" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Turi pradžios datą" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Pradžios data prieš" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Pradžios data po" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Turi tikslinę datą" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Tikslinė data prieš" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Tikslinė data po" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Užbaigta prieš" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Užbaigta po" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Minimali data" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Maksimali data" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Neįtraukti medžio struktūros" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Prieš ištrinant gamybą, ji turi būti atšaukta" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Sunaudojama" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Pasirinktinai" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Surinkimas" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Sekama" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testuojama" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Liko neįvykdytų užsakymų" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Priskirta" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Užsakyta" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Gamybos užsakymas" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Vieta" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Gamybos užsakymai" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Surinkimo BOM nėra patvirtintas" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Negalima sukurti gamybos užsakymo neaktyviai detalei" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Negalima sukurti gamybos užsakymo atrakintai detalei" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Turi būti nurodytas atsakingas vartotojas arba grupė" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Gamybos užsakymo detalės keisti negalima" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Tikslinė data turi būti po pradžios datos" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Gamybos užsakymo nuoroda" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Gamybos užsakymo nuoroda" msgid "Reference" msgstr "Nuoroda" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Trumpas gamybos aprašymas (neprivalomas)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Pasirinkite detalę gamybai" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Pardavimo užsakymo nuoroda" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Šaltinio vieta" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Paskirties vieta" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Pasirinkite vietą, kur bus laikomos užbaigtos prekės" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Gamybos kiekis" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Atsargų kiekis, kurias reikia pagaminti" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Užbaigtos prekės" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Užbaigtų atsargų elementų skaičius" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Gamybos būsena" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Gamybos būsenos kodas" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Partijos kodas" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Šios gamybos partijos kodas" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Sukūrimo data" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Gamybos pradžios data" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Planuojama šio gamybos užsakymo pradžios data" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Tikslinė užbaigimo data" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Užbaigimo data" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "Užbaigė" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Išdavė" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Vartotojas, kuris išdavė šį gamybos užsakymą" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Atsakingas" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Vartotojas ar grupė, atsakinga už šį gamybos užsakymą" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Išorinė nuoroda" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Nuoroda į išorinį URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Gamybos prioritetas" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Šio gamybos užsakymo prioritetas" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Projekto kodas" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Šio gamybos užsakymo projekto kodas" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Gamybos užsakymas {build} užbaigtas" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Gamybos užsakymas užbaigtas" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Sekamoms detalėms būtina nurodyti serijos numerius" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nepateiktas gamybos rezultatas" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Gamybos rezultatas jau užbaigtas" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Gamybos rezultatas neatitinka gamybos užsakymo" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Kiekis turi būti didesnis nei nulis" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Kiekis negali viršyti rezultato kiekio" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Gamybos užsakymo eilutės įrašas" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Gamybos objektas" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Kiekis" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Reikalingas kiekis gamybos užsakymui" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Pasirinktas atsargų elementas neatitinka BOM eilutės" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Atsargoms su serijos numeriais kiekis turi būti 1" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Atsargų elementas per daug paskirstytas" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Atsargų elementas" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Šaltinio atsargų elementas" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Atsargų kiekis, skirtas paskirstyti į gamybą" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Įdiegti į" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Paskirties atsargų elementas" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Gamybos lygis" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Detalės pavadinimas" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Gamybos rezultatas" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Gamybos rezultatas neatitinka pirminės gamybos" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Rezultato detalė neatitinka gamybos užsakymo detalės" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Šis gamybos rezultatas jau užbaigtas" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Šis gamybos rezultatas nėra visiškai paskirstytas" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Įveskite kiekį gamybos rezultatui" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Sekamoms detalėms reikalingas sveikasis kiekis" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serijos numeriai" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Įveskite serijos numerius gamybos rezultatams" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Atsargų vieta gamybos rezultatams" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automatiškai priskirti serijos numerius" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatiškai priskirti reikalingas prekes su atitinkančiais serijos numeriais" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Šie serijos numeriai jau egzistuoja arba yra neteisingi" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Turi būti pateiktas gamybos rezultatų sąrašas" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Atsargų vieta brokuotiems rezultatams" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Atmesti priskyrimus" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Atmesti visus atsargų priskyrimus brokuotiems rezultatams" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Priežastis, dėl kurios gamybos rezultatas(-ai) buvo nurašytas(-i)" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Vieta, kur laikomi užbaigti gamybos rezultatai" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Priimti nepilną priskyrimą" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Sunaudoti priskirtas atsargas" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "Sunaudoti bet kokias šiai gamybai jau priskirtas atsargas" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Pašalinti nebaigtus rezultatus" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Ištrinti visus nebaigtus gamybos rezultatus" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Neleidžiama" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Priimti kaip sunaudotą šio gamybos užsakymo metu" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Panaikinkite priskyrimus prieš užbaigiant šį gamybos užsakymą" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Per daug paskirstytos atsargos" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Kai kurios atsargos paskirstytos per daug" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Priimti nepriskirtą" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Reikalingos atsargos nėra visiškai priskirtos" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Priimti nepilną" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Reikalingas gamybos kiekis nebuvo užbaigtas" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Gamybos užsakymas turi nebaigtų antrinių gamybų" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Gamybos užsakymas turi būti gamybos būsenoje" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Gamybos užsakymas turi nebaigtų rezultatų" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Gamybos eilutė" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Gamybos rezultatas" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Gamybos rezultatas turi būti susietas su ta pačia gamyba" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Gamybos eilutės įrašas" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Prekė turi būti atsargose" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "Sekamų detalių priskyrymui turi būti nurodytas gamybos rezultatas" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Negalima nurodyti gamybos rezultato nesekamoms detalėms" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Turi būti pateikti paskirstymo elementai" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Neįtraukti vietos" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Neįtraukti atsargų iš šios pasirinktos vietos" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Keičiamos atsargos" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Atsargos iš skirtingų vietų gali būti naudojamos pakaitomis" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Pakaitinės atsargos" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Leisti priskirti pakaitines detales" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Pasirenkami elementai" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Priskirti papildomus BOM elementus gamybos užsakymui" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Nepavyko paleisti automatinio paskirstymo užduoties" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "BOM nuoroda" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "BOM detalės ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "BOM detalės pavadinimas" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Gamyba" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Tiekėjo detalė" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Priskirtas kiekis" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Gamybos nuoroda" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Detalės kategorijos pavadinimas" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Sekama" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Paveldėta" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Leisti variantus" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "BOM elementas" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Gamyboje" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Išorinės atsargos" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Prieinamos atsargos" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Prieinamos pakaitinės atsargos" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Prieinamos variantų atsargos" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "Sulaikyta" msgid "Cancelled" msgstr "Atšaukta" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Užbaigta" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Atsargos, reikalingos gamybos užsakymui" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Vėluojantis gamybos užsakymas" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Gamybos užsakymas {bo} dabar vėluoja" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Yra nuoroda" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Yra failas" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Vartotojas neturi teisės ištrinti šių priedų" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Vartotojas neturi teisės ištrinti šio priedo" @@ -1551,798 +1539,822 @@ msgstr "Nepateikta jokių galiojančių valiutos kodų" msgid "No plugin" msgstr "Nėra papildinio" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Projekto kodo etiketė" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Atnaujinta" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Paskutinio atnaujinimo laiko žymė" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unikalus projekto kodas" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projekto aprašymas" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Vartotojas arba grupė, atsakinga už šį projektą" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Nustatymo raktas" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Nustatymo reikšmė" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Pasirinkta reikšmė yra netinkama" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Reikšmė turi būti loginė (taip/ne)" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Reikšmė turi būti sveikasis skaičius" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Reikšmė turi būti tinkamas skaičius" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Reikšmė neatitinka patikros taisyklių" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Raktas turi būti unikalus" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Vartotojas" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Kiekio ribinis taškas kainai" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Kaina" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Vieneto kaina nurodytam kiekiui" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Galutinis taškas" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Galutinis taškas, kuriuo priimamas šis webhook'as" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Šio webhook'o pavadinimas" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktyvus" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Ar šis webhook'as aktyvus" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Raktas" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Prieigos raktas" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Slaptas raktas" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Bendras slaptas HMAC raktas" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Pranešimo ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Unikalus pranešimo identifikatorius" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Pagrindinis serveris" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Serveris, iš kurio gautas pranešimas" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Antraštė" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Šio pranešimo antraštė" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Turinys" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Šio pranešimo turinys" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Galutinis taškas, kuriame gautas pranešimas" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Apdorota" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Ar darbas su šiuo pranešimu baigtas?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "ID" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Pavadinimas" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Nuoroda" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Paskelbta" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autorius" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Santrauka" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Perskaityta" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Ar ši naujiena buvo perskaityta?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Paveikslėlio failas" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Modelio tipas, kuriam priskiriamas šis paveikslėlis" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "Modelio ID, kuriam priskiriamas šis paveikslėlis" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Pasirinktinis vienetas" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Vieneto simbolis turi būti unikalus" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Vieneto pavadinimas turi būti tinkamas identifikatorius" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Vieneto pavadinimas" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Simbolis" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Nebūtinas vieneto simbolis" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Apibrėžimas" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Vieneto apibrėžimas" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Priedas" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Trūksta failo" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Trūksta išorinės nuorodos" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Modelio tipas" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Modelio tipas, kuriam skirtas paveikslėlis" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Pasirinkite failą priedui" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentaras" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Komentaras prie priedo" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Įkėlimo data" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Failo įkėlimo data" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Failo dydis" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Failo dydis baitais" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Netinkamas modelio tipas priedui" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Pasirinktinė būsena" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Pasirinktinės būsenos" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Nuorodos būsenų rinkinys" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Būsenų rinkinys, papildomas šia pasirinktine būsena" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Loginis raktas" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Reikšmė" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Skaitinė reikšmė, saugoma modelio duomenų bazėje" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Būsenos pavadinimas" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiketė" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiketė, rodoma vartotojo sąsajoje" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Spalva" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Spalva, rodoma vartotojo sąsajoje" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modelis" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Modelis, su kuriuo susieta būsena" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Turi būti pasirinktas modelis" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Turi būti pasirinktas raktas" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Turi būti pasirinktas loginis raktas" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Raktas turi skirtis nuo loginio rakto" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Turi būti pateikta tinkama nuorodos būsenos klasė" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "Pavadinimas turi skirtis nuo nuorodos būsenų pavadinimų" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Pasirinkimų sąrašas" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Pasirinkimų sąrašai" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Pasirinkimų sąrašo pavadinimas" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Pasirinkimų sąrašo aprašymas" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Užrakinta" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Ar šis sąrašas užrakintas?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Ar šį pasirinkimų sąrašą galima naudoti?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Šaltinio papildinys" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Papildinys, pateikiantis šį pasirinkimų sąrašą" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Šaltinio eilutė" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Neprivaloma eilutė, identifikuojanti šaltinį, naudotą šiam sąrašui" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Numatytasis įrašas" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Numatytasis šio pasirinkimų sąrašo įrašas" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Sukurta" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Data ir laikas, kada buvo sukurtas pasirinkimų sąrašas" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Paskutinį kartą atnaujinta" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Pasirinkimų sąrašo įrašas" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Pasirinkimų sąrašo įrašai" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Pasirinkimų sąrašas, kuriam priklauso šis įrašas" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Pasirinkimų sąrašo įrašo reikšmė" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Pasirinkimų įrašo etiketė" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Pasirinkimų įrašo aprašymas" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Ar šis sąrašo įrašas aktyvus?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parametro šablonas" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Žymimojo laukelio parametrai negali turėti matavimo vienetų" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Žymimojo laukelio parametrai negali turėti pasirinkimų" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Pasirinkimai turi būti unikalūs" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Parametro šablono pavadinimas turi būti unikalus" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Parametro pavadinimas" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Vienetai" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Fiziniai šio parametro vienetai" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Parametro aprašymas" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Žymimasis laukelis" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Ar šis parametras yra žymimasis laukelis?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Pasirinkimai" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Galimi pasirinkimai šiam parametrui (atskirti kableliais)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Pasirinkimų sąrašas šiam parametrui" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Įjungta" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Neteisingas pasirinkimas parametro reikšmei" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Šablonas" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Data" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Parametro reikšmė" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Pastaba" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Neprivalomas pastabų laukas" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Brūkšninio kodo nuskaitymas" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Brūkšninio kodo duomenys" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Vartotojas, nuskaitęs brūkšninį kodą" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Laiko žymė" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Brūkšninio kodo nuskaitymo data ir laikas" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "URL galutinis taškas, kuris apdorojo brūkšninį kodą" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontekstas" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Konteksto duomenys brūkšninio kodo nuskaitymui" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Atsakas" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Atsako duomenys iš brūkšninio kodo nuskaitymo" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Rezultatas" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Ar brūkšninio kodo nuskaitymas buvo sėkmingas?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Raktas" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Gautos prekės" @@ -2392,1235 +2404,1303 @@ msgstr "Nurodo, ar nustatymą pakeičia aplinkos kintamasis" msgid "Override" msgstr "Nepaisyti" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Vykdoma" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Laukiančios užduotys" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Suplanuotos užduotys" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Nepavykusios užduotys" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Užduoties ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Unikalus užduoties ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Užraktas" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Užrakto laikas" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Užduoties pavadinimas" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funkcija" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funkcijos pavadinimas" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumentai" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Užduoties argumentai" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Rakto argumentai" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Užduoties rakto argumentai" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Failo pavadinimas" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Modelio tipas" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: 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:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Nėra grupės" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Svetainės URL yra užrakintas konfigūracijoje" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Reikalingas paleidimas iš naujo" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Nustatymas buvo pakeistas ir reikia paleisti serverį iš naujo" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Laukiančios migracijos" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Laukiančių duomenų bazės migracijų skaičius" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "Egzemplioriaus ID" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Unikalus identifikatorius šiam InvenTree egzemplioriui" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Pranešimo ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Skelbti serverio egzemplioriaus ID serverio būsenos informacijoje (neprisijungus)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Serverio egzemplioriaus pavadinimas" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Serverio egzemplioriaus pavadinimas kaip eilutė" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Naudoti egzemplioriaus pavadinimą" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Naudoti egzemplioriaus pavadinimą antraštės juostoje" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Apriboti `apie` rodymą" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "`Apie` langą rodyti tik super-vartotojams" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Įmonės pavadinimas" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Vidinis įmonės pavadinimas" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Pagrindinis URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Pagrindinis URL šiam serverio egzemplioriui" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Numatytoji valiuta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Pasirinkti pagrindinę valiutą kainų skaičiavimui" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Palaikomos valiutos" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Palaikomų valiutų kodų sąrašas" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Valiutų atnaujinimo intervalas" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dienos" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Valiutų atnaujinimo papildinys" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Naudotinas valiutų atnaujinimo papildinys" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Atsisiųsti iš URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Leisti atsisiųsti išorinius paveikslėlius ir failus iš nuorodų" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Atsisiuntimo dydžio riba" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Didžiausias leistinas atsisiunčiamo paveikslėlio dydis" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Naudojamas user-agent atsisiuntimui iš URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Leisti pakeisti user-agent, naudojamą atsisiunčiant paveikslėlius ir failus iš išorinio URL (palikite tuščią, jei naudoti numatytąjį)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Griežtas URL tikrinimas" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Reikalauti schemos nurodymo tikrinant URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Atnaujinimų tikrinimo intervalas" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Kaip dažnai tikrinti atnaujinimus (nulis – išjungti)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatinė atsarginė kopija" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Įjungti automatinį duomenų bazės ir failų atsarginį kopijavimą" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automatinio atsarginės kopijos kūrimo intervalas" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Nurodykite dienų skaičių tarp atsarginių kopijų kūrimo" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Užduočių ištrynimo intervalas" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Foninių užduočių rezultatai bus ištrinti po nurodyto dienų skaičiaus" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Klaidų žurnalo ištrynimo intervalas" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Klaidų žurnalai bus ištrinti po nurodyto dienų skaičiaus" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Pranešimų ištrynimo intervalas" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Vartotojų pranešimai bus ištrinti po nurodyto dienų skaičiaus" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Brūkšninių kodų palaikymas" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Įjungti brūkšninių kodų skaitytuvo palaikymą žiniatinklio sąsajoje" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Išsaugoti brūkšninių kodų nuskaitymus" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Brūkšninių kodų nuskaitymo rezultatus išsaugoti duomenų bazėje" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maksimalus nuskaitymų skaičius" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Maksimalus saugomų brūkšninių kodų nuskaitymų skaičius" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Brūkšninio kodo įvesties delsimas" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Brūkšninio kodo įvesties apdorojimo delsos laikas" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Brūkšninių kodų palaikymas per kamerą" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Leisti brūkšninių kodų nuskaitymą per naršyklės kamerą" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Rodyti brūkšninio kodo duomenis" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Rodyti brūkšninio kodo duomenis naršyklėje kaip tekstą" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Brūkšninio kodo generavimo papildinys" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Papildinys vidiniam brūkšninių kodų generavimui" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Detalių versijos" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Įjungti versijos lauką detalėms" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Tik surinkimo versijoms" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Leisti versijas tik surenkamoms detalėms" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Leisti pašalinti iš surinkimo" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "Leisti ištrinti detales, kurios yra naudojamos surinkimuose" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN reguliarioji išraiška" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Reguliariosios išraiškos šablonas detalių IPN tikrinimui" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Leisti pasikartojančius IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Leisti kelioms detalėms turėti tą patį IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Leisti redaguoti IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "Leisti keisti IPN reikšmę redaguojant detalę" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Kopijuoti detalės BOM duomenis" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopijuoti BOM duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Kopijuoti detalės parametrus" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "Kopijuoti parametrų duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Kopijuoti detalės testavimo duomenis" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "Kopijuoti testavimo duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kopijuoti kategorijų parametrų šablonus" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Kopijuoti kategorijų parametrų šablonus kuriant detalę" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Detalės pagal nutylėjimą yra šablonai" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponentas" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Galima įsigyti" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Detalės pagal nutylėjimą gali būti įsigyjamos" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Parduodama" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Detalės pagal nutylėjimą gali būti parduodamos" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Detalės pagal nutylėjimą gali būti sekamos" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuali" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Detalės pagal nutylėjimą yra virtualios" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Rodyti susijusias detales" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Rodyti susijusias detales pasirinktai detalei" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Pradiniai atsargų duomenys" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "Leisti sukurti pradinę atsargą pridedant naują detalę" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Pradiniai tiekėjo duomenys" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Detalės pavadinimo rodymo formatas" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Detalės pavadinimo rodymo formatas" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Detalės kategorijos numatytoji piktograma" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Mažiausias kainos dešimtainių skaičių kiekis" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Didžiausias kainos dešimtainių skaičių kiekis" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Naudoti tiekėjo kainas" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Įtraukti tiekėjų kainų lygius į bendrą kainodaros skaičiavimą" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Pirkimų istorija keičia kainas" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Istorinės pirkimo kainos pakeičia tiekėjo kainų lygius" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Naudoti atsargų kainas" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Atsargų kainų galiojimo trukmė" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Naudoti variantų kainas" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Įtraukti variantų kainas į bendrą kainodaros skaičiavimą" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Tik aktyvūs variantai" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Naudoti tik aktyvius detalių variantus kainodarai" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Kainodaros atnaujinimo intervalas" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "Dienų skaičius iki automatinio detalių kainų atnaujinimo" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Vidinės kainos" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Įjungti vidines kainas detalėms" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Vidinės kainos viršenybė" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Įjungti etikečių spausdinimą" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Įjungti etikečių spausdinimą iš žiniatinklio sąsajos" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Etiketės vaizdo DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Įjungti ataskaitas" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Įjungti ataskaitų generavimą" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Derinimo režimas" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Generuoti ataskaitas derinimo režimu (HTML išvestis)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Registruoti ataskaitų klaidas" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registruoti klaidas, įvykusias generuojant ataskaitas" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Puslapio dydis" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Numatytasis PDF ataskaitų puslapio dydis" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Reikalauti parametrų vienetų" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globaliai unikalūs serijiniai numeriai" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Atsargų serijos numeriai turi būti globaliai unikalūs" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Ištrinti išnaudotas atsargas" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "Nustato numatytą elgseną, kai atsargos yra išnaudotos" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Partijos kodo šablonas" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Šablonas numatytiesiems atsargų partijos kodams generuoti" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Atsargų galiojimas" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Įjungti atsargų galiojimo funkcionalumą" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Parduoti pasibaigusias galioti atsargas" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Leisti parduoti pasibaigusias galioti atsargas" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Atsargų senėjimo laikas" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Naudoti pasibaigusias galioti atsargas gamyboje" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Leisti naudoti pasibaigusias galioti atsargas gamyboje" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Atsargų nuosavybės kontrolė" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Įjungti atsargų vietų ir vienetų nuosavybės kontrolę" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Atsargų vietos numatytoji piktograma" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Atsargų vietos numatytoji piktograma (tuščia reiškia nenaudojama)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Rodyti sumontuotas atsargas" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Rodyti sumontuotas atsargas atsargų lentelėse" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Tikrinti BOM montuojant atsargas" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Leisti perkelti neturimas atsargas" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Gamybos užsakymo nuorodos šablonas" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Privalomas šablonas gamybos užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Reikalauti atsakingo savininko" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Kiekvienam užsakymui turi būti priskirtas atsakingas savininkas" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Reikalauti aktyvios detalės" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Neleidžia kurti gamybos užsakymų neaktyvioms detalėms" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Reikalauti užrakintos detalės" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Neleidžia kurti gamybos užsakymų neužrakintoms detalėms" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Reikalauti galiojančio komplektavimo sąrašo (BOM)" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Reikalauti uždarytų antrinių užsakymų" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blokuoti, kol testai bus išlaikyti" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Įjungti grąžinimo užsakymus" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Įjungia grąžinimo užsakymų funkciją vartotojo sąsajoje" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Grąžinimo užsakymo nuorodos šablonas" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Būtinas šablonas grąžinimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Redaguoti užbaigtus grąžinimo užsakymus" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Pardavimo užsakymo nuorodos šablonas" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Būtinas šablonas pardavimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Numatytasis siuntinys pardavimo užsakymui" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Leisti automatiškai sukurti siuntinį kartu su pardavimo užsakymu" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Redaguoti užbaigtus pardavimo užsakymus" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Pažymėti išsiųstus užsakymus kaip užbaigtus" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Pirkimo užsakymo nuorodos šablonas" -#: common/setting/system.py:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "Būtinas šablonas pirkimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Redaguoti užbaigtus pirkimo užsakymus" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Konvertuoti valiutą" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "Konvertuoti prekių vertę į pagrindinę valiutą priimant prekes" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Automatiškai užbaigti pirkimo užsakymus" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Įjungti pamiršto slaptažodžio funkciją" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Leisti naudoti pamiršto slaptažodžio funkciją prisijungimo puslapyje" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Įjungti registraciją" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "Leisti vartotojams savarankiškai registruotis prisijungimo puslapyje" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Įjungti vieningą prisijungimą (SSO)" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Įjungti vieningą prisijungimą (SSO) prisijungimo puslapyje" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Įjungti registraciją per SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Leisti vartotojams registruotis per SSO prisijungimo puslapyje" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Įjungti SSO grupių sinchronizavimą" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO grupės raktas" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSO grupių susiejimas" -#: common/setting/system.py:966 +#: 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 "SSO grupių susiejimas su vietinėmis InvenTree grupėmis. Jei vietinė grupė neegzistuoja, ji bus sukurta." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Pašalinti grupes, nepriklausančias SSO" -#: common/setting/system.py:974 +#: 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 "Ar pašalinti vartotojui priskirtas grupes, jei jos nėra pateikiamos per IdP. Išjungus gali kilti saugumo problemų" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "El. paštas privalomas" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Reikalauti vartotojo el. pašto registracijos metu" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Automatiškai užpildyti SSO naudotojų duomenis" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Įvesti el. paštą du kartus" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Įvesti slaptažodį du kartus" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "Registracijos metu prašyti vartotojų du kartus įvesti slaptažodį" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Leidžiami domenai" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Riboti registraciją tik tam tikriems domenams (atskiriama kableliais, prasideda @)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupė registruojantis" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Reikalauti kelių veiksnių autentifikacijos (MFA)" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Vartotojai privalo naudoti kelių veiksnių apsaugą." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Tikrinti įskiepius paleidimo metu" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Tikrinti įskiepių atnaujinimus" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Įjungti periodinius įdiegtų įskiepių atnaujinimų tikrinimus" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Įjungti URL integravimą" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Leisti įskiepiams pridėti URL maršrutus" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Įjungti navigacijos integraciją" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Leisti įskiepiams integruotis į navigaciją" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Įjungti programų integraciją" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Leisti įskiepiams pridėti programas" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Įjungti planavimo integraciją" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Leisti įskiepiams vykdyti suplanuotas užduotis" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Įjungti įvykių integraciją" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Leisti įskiepiams reaguoti į vidinius įvykius" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Įjungti sąsajos integraciją" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Leisti įskiepiams integruotis į vartotojo sąsają" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Įjungti projektų kodus" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Įjungti projektų kodų naudojimą projektų sekimui" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Neįtraukti išorinių vietų" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Automatinės inventorizacijos periodas" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Rodyti pilnus vartotojų vardus" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Rodyti pilnus vardus vietoj vartotojo vardų" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Rodyti vartotojų profilius" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Rodyti vartotojų profilius jų paskyros puslapyje" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Įjungti bandymų stoties duomenis" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Įjungti bandymų stoties duomenų rinkimą testų rezultatams" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Gauti klaidų ataskaitas" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Gauti pranešimus apie sistemos klaidas" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Paskutiniai naudoti spausdintuvai" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "Išsaugoti paskutinius naudotojo naudotus spausdintuvus" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Detalė yra aktyvi" msgid "Manufacturer is Active" msgstr "Gamintojas yra aktyvus" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Tiekėjo detalė yra aktyvi" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Vidinė detalė yra aktyvi" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Tiekėjas yra aktyvus" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Gamintojas" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Įmonė" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Turi atsargų" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Įmonės" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Įmonės aprašymas" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Įmonės aprašymas" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Tinklalapis" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Įmonės tinklalapio URL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefono numeris" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kontaininis telefono numeris" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontaktinis el. pašto adresas" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontaktinis asmuo" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Kontaktinis asmuo" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Nuoroda į išorinę įmonės informaciją" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Ar ši įmonė aktyvi?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Yra klientas" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Ar parduodate prekes šiai įmonei?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Yra tiekėjas" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Ar perkate prekes iš šios įmonės?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Yra gamintojas" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Ar ši įmonė gamina detales?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Numatytoji valiuta, naudojama šiai įmonei" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adresas" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adresai" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Pasirinkite įmonę" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Adreso pavadinimas" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Pavadinimas, apibūdinantis adreso įrašą" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Pagrindinis adresas" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Nustatyti kaip pagrindinį adresą" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "1-a eilutė" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adreso 1-a eilutė" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "2-a eilutė" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adreso 2-a eilutė" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Pašto kodas" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Miestas / regionas" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Pašto kodas, miestas / regionas" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Valstija / provincija" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Valstija arba provincija" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Šalis" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adreso šalis" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Kurjerio siuntos pastabos" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Pastabos siuntų kurjeriui" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Vidinės siuntos pastabos" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Siuntimo pastabos vidiniam naudojimui" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Nuoroda į adreso informaciją (išorinė)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Gamintojo detalė" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Pagrindinė detalė" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Pasirinkite detalę" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Pasirinkite gamintoją" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Gamintojo detalės numeris (MPN)" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "Išorinės nuorodos į gamintojo detalės URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Gamintojo detalės aprašymas" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Pakuotės vienetų kiekis turi būti didesnis už nulį" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Susieta gamintojo detalė turi nurodyti tą pačią pagrindinę detalę" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tiekėjas" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Pasirinkite tiekėją" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Tiekėjo sandėlio numeris (SKU)" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Ar ši tiekėjo detalė aktyvi?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Pasirinkite gamintojo detalę" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Išorinės nuorodos į tiekėjo detalės URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Tiekėjo detalės aprašymas" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "bazinė kaina" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimalus mokestis (pvz., sandėliavimo mokestis)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Pakuotė" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Detalės pakuotė" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Pakuotės kiekis" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "daugiklis" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Užsakymo daugiklis" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Tiekėjo turimas kiekis" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Prieinamumas atnaujintas" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Paskutinio prieinamumo duomenų atnaujinimo data" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Tiekėjo kainos ribos" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Numatytoji valiuta, naudojama šiam tiekėjui" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Įmonės pavadinimas" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Sandėlyje" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Įvyko klaida eksportuojant duomenis" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Šis stulpelis jau yra susietas su duomenų bazės lauku" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Šis laukas jau yra susietas su duomenų stulpeliu" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Stulpelis neegzistuoja duomenų faile" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Laukas neegzistuoja tiksliniame modelyje" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Pasirinktas laukas yra tik skaitomas" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Importavimo sesija" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Laukas" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Stulpelis" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Eilutės indeksas" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Pradiniai eilutės duomenys" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Klaidos" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Galiojantis" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Etiketės spausdinamų kopijų skaičius" msgid "Connected" msgstr "Prijungta" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Nežinoma" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupė" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Užsakymo nuoroda" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Neįvykdyta" @@ -4728,7 +4828,7 @@ msgstr "Neįvykdyta" msgid "Has Project Code" msgstr "Turi projekto kodą" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Sukūrė" @@ -4764,57 +4864,69 @@ msgstr "Tikslinė data prieš" msgid "Target Date After" msgstr "Tikslinė data po" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Turi kainodarą" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Užbaigta prieš" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Užbaigta po" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Užsakymas" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Užsakymas įvykdytas" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Vidinė detalė" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Užsakymas laukia vykdymo" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Užbaigta" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Turi siuntą" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Pirkimo užsakymas" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Pirkimo užsakymas" msgid "Sales Order" msgstr "Pardavimo užsakymas" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Bendra kaina" msgid "Total price for this order" msgstr "Bendra kaina už šį užsakymą" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Užsakymo valiuta" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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ą)" @@ -4851,718 +4963,750 @@ msgstr "Užsakymo valiuta (palikite tuščią, jei norite naudoti įmonės numat msgid "This order is locked and cannot be modified" msgstr "Šis užsakymas užrakintas ir negali būti keičiamas" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Kontaktas nesutampa su pasirinkta įmone" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Pradžios data turi būti prieš tikslinę datą" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Užsakymo aprašymas (neprivalomas)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Pasirinkite projekto kodą šiam užsakymui" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Nuoroda į išorinį puslapį" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Pradžios data" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Numatyta pradžios data šiam užsakymui" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Tikslinė data" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Išdavimo data" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Data, kada užsakymas buvo išduotas" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Vartotojas arba grupė, atsakinga už šį užsakymą" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Kontaktinis asmuo šiam užsakymui" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Įmonės adresas šiam užsakymui" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Užsakymo nuoroda" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Būsena" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Pirkimo užsakymo būsena" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Įmonė, iš kurios užsakomos prekės" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Tiekėjo nuoroda" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Tiekėjo užsakymo nuorodos kodas" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "gavo" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Data, kada užsakymas buvo užbaigtas" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Paskirties vieta" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Paskirties vieta gautoms prekėms" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Detalių tiekėjas turi atitikti pirkimo užsakymo tiekėją" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Eilutės įrašas neatitinka pirkimo užsakymo" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Kiekis turi būti teigiamas skaičius" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klientas" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Įmonė, kuriai prekės parduodamos" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Pardavimo užsakymo būsena" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Kliento nuoroda" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Kliento užsakymo nuorodos kodas" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Siuntos data" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "išsiuntė" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Užsakymas jau baigtas" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Užsakymas jau atšauktas" -#: order/models.py:1423 +#: order/models.py:1463 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:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Užsakymas užrakintas ir negali būti keičiamas" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Prekės kiekis" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Eilutės įrašo nuoroda" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Eilutės įrašo pastabos" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Eilutės įrašo aprašymas (neprivalomas)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Papildomas kontekstas šiai eilutei" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Vieneto kaina" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Pirkimo užsakymo eilutės įrašas" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Tiekėjo detalė turi atitikti tiekėją" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Tiekėjo detalė" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Gauta" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Gautų prekių kiekis" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Pirkimo kaina" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Vieneto pirkimo kaina" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Pirkimo užsakymo papildoma eilutė" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Pardavimo užsakymo eilutės įrašas" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Pardavimo kaina" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Vieneto pardavimo kaina" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Išsiųsta" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Išsiųstas kiekis" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Pardavimo užsakymo siunta" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Siuntos data" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Pristatymo data" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Siuntos pristatymo data" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Patikrino" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Vartotojas, patikrinęs šią siuntą" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Siunta" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Siuntos numeris" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Sekimo numeris" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Siuntos sekimo informacija" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Sąskaitos faktūros numeris" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Nuorodos numeris susijusiai sąskaitai faktūrai" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Siunta jau buvo išsiųsta" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Siunta neturi priskirtų prekių" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Pardavimo užsakymo papildoma eilutė" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Pardavimo užsakymo paskirstymas" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Prekė nėra priskirta" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "Negalima priskirti prekių eilutei su skirtinga detale" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Negalima priskirti prekių eilutei, jei joje nėra detalės" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Priskiriamas kiekis negali viršyti atsargų kiekio" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Priskirtas kiekis turi būti didesnis nei nulis" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Kiekis turi būti 1, jei prekė turi serijos numerį" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Pardavimo užsakymas nesutampa su siunta" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Siunta nesutampa su pardavimo užsakymu" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Eilutė" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Pardavimo užsakymo siuntos nuoroda" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Prekė" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Pasirinkite atsargų elementą priskyrimui" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Įveskite prekių priskyrimo kiekį" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Grąžinimo užsakymo nuoroda" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Įmonė, iš kurios grąžinamos prekės" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Grąžinimo užsakymo būsena" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Grąžinimo užsakymo eilutės įrašas" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Turi būti nurodytas atsargų elementas" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Grąžinamo kiekis viršija prekių kiekį" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Grąžinamo kiekis turi būti daugiau nei nulis" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Neteisingas kiekis serijinio numerio prekei" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Pasirinkite prekę grąžinimui iš kliento" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Gavimo data" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Rezultatas" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Rezultatas šiam eilutės įrašui" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Grąžinimo užsakymo papildoma eilutė" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Užsakymo ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "Užsakymo, kurį reikia dubliuoti, ID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Kopijuoti eilutes" -#: order/serializers.py:88 +#: 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:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Kopijuoti papildomas eilutes" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Kopijuoti papildomas eilutes iš pradinio užsakymo" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Eilutės įrašai" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Užbaigtos eilutės" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Dubliuoti užsakymą" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Nurodykite užsakymo dubliavimo parinktis" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Neteisingas užsakymo ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Tiekėjo pavadinimas" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Užsakymo atšaukti negalima" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Užsakyme yra neužbaigtų eilutės įrašų" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Užsakymas nėra atidarytas" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automatinis kainų nustatymas" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Pirkimo kainos valiuta" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Sujungti elementus" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Vidinis detalės numeris" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Vidinis detalės pavadinimas" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Turi būti nurodyta tiekėjo detalė" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Turi būti nurodytas pirkimo užsakymas" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Tiekėjas turi atitikti pirkimo užsakymą" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Pirkimo užsakymas turi atitikti tiekėją" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Eilutės įrašas" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Pasirinkite paskirties vietą gautiems elementams" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Įveskite partijos kodą gaunamoms atsargoms" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Galiojimo data" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Įveskite galiojimo datą gaunamoms atsargoms" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Įveskite gaunamų atsargų serijos numerius" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Pakeisti gaunamų atsargų pakavimo informaciją" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Papildoma pastaba gaunamoms atsargoms" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Brūkšninis kodas" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Nuskaitytas brūkšninis kodas" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Brūkšninis kodas jau naudojamas" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Turi būti pateikti eilutės įrašai" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Turi būti nurodyta paskirties vieta" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Pateiktos brūkšninių kodų reikšmės turi būti unikalios" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Siuntos" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Užbaigtos siuntos" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Pardavimo kainos valiuta" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Paskirstyti elementai" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nepateikta siuntos informacija" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Kiekis turi būti teigiamas" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Įveskite priskiriamus serijos numerius" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Siunta jau išsiųsta" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Siunta nėra susieta su šiuo užsakymu" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Nerasta atitikmenų šiems serijos numeriams" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Šie serijos numeriai nepasiekiami" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Grąžinimo užsakymo eilutės įrašas" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Eilutės įrašas neatitinka grąžinimo užsakymo" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Eilutės įrašas jau gautas" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Grąžinamas kiekis" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Eilutės kainos valiuta" @@ -5598,146 +5742,150 @@ msgstr "Pinigų grąžinimas" msgid "Reject" msgstr "Atmesti" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Vėluojantis pirkimo užsakymas" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Pirkimo užsakymas {po} dabar vėluoja" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Vėluojantis pardavimo užsakymas" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Pardavimo užsakymas {so} dabar vėluoja" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Vėluojantis grąžinimo užsakymas" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Grąžinimo užsakymas {ro} dabar vėluoja" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Pažymėta žvaigždute" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filtruoti pagal pažymėtas kategorijas" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Gylis" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtruoti pagal kategorijos gylį" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Aukščiausio lygio" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtruoti pagal aukščiausio lygio kategorijas" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Kaskada" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Įtraukti sub-kategorijas į filtravimo rezultatus" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Pirminė kategorija" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filtruoti pagal pirminę kategoriją" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Neįtraukti sub-kategorijų po nurodyta kategorija" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Turi rezultatų" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Yra variantas" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Yra versija" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Turi versijų" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "BOM galiojantis" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Surinkimo detalė gali būti testuojama" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Komponento detalė gali būti testuojama" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Naudoja" @@ -5746,11 +5894,11 @@ msgstr "Naudoja" msgid "Part Category" msgstr "Detalių kategorija" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Detalių kategorijos" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Numatytoji vieta" @@ -5778,7 +5926,7 @@ msgstr "Numatytieji raktažodžiai detalėms šioje kategorijoje" msgid "Icon" msgstr "Piktograma" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Piktograma (neprivaloma)" @@ -5799,1025 +5947,1050 @@ msgstr "Numatytoji reikšmė" msgid "Default Parameter Value" msgstr "Numatytoji parametro reikšmė" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Detalės" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Negalima ištrinti šios detalės, nes ji užrakinta" -#: part/models.py:593 +#: part/models.py:594 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:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN turi atitikti regex šabloną {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Detalė negali būti savo pačios versija" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Negalima sukurti detalės versijos, jei tai jau yra kita versija" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Turi būti nurodytas versijos kodas" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Versijos leidžiamos tik surinkimo detalėms" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Negalima sukurti šabloninės detalės versijos" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Pagrindinė detalė turi būti susieta su tuo pačiu šablonu" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Atsargų elementas su šiuo serijos numeriu jau egzistuoja" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN dublikatų detalių nustatymuose naudoti negalima" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Tokia detalės versija jau egzistuoja." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Detalė su tokiu pavadinimu, IPN ir versija jau egzistuoja." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Detalės negali būti priskirtos struktūrinėms detalių kategorijoms!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Detalės pavadinimas" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Yra šablonas" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Ar ši detalė yra šabloninė detalė?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Ar ši detalė yra kitos detalės variantas?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variantas iš" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Detalės aprašymas (neprivalomas)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Raktažodžiai" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Detalės raktažodžiai, skirti pagerinti matomumą paieškos rezultatuose" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Detalės kategorija" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Detalės versija arba numeris" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Versija" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Ar ši detalė yra kitos detalės versija?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Versija iš" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Kur ši detalė paprastai laikoma?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Numatytasis galiojimo laikas" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Šios detalės atsargų galiojimo laikas (dienomis)" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimalus atsargų kiekis" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Mažiausias leidžiamas atsargų kiekis" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Šios detalės matavimo vienetai" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Ar ši detalė gali būti pagaminta iš kitų detalių?" -#: part/models.py:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Ar ši detalė turi unikalių vienetų sekimą?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Ar šiai detalei gali būti priskirti bandymų rezultatai?" -#: part/models.py:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Ar ši detalė gali būti parduodama klientams?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Ar ši detalė yra aktyvi?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Užrakintos detalės negali būti redaguojamos" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "BOM kontrolinė suma" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Išsaugota BOM kontrolinė suma" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Detalių sąrašą patikrino" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Detalių sąrašo patikrinimo data" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Sukūręs vartotojas" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Atsakingas vartotojas už šią detalę" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Parduodamas kiekis" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Valiuta, naudojama kainų skaičiavimams kaupti" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimali BOM kaina" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minimali komponentų detalių kaina" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maksimali BOM kaina" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maksimali komponentų detalių kaina" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimali pirkimo kaina" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Mažiausia istorinė pirkimo kaina" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maksimali pirkimo kaina" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Didžiausia istorinė pirkimo kaina" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimali vidinė kaina" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Mažiausia kaina pagal vidinius kainų intervalus" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maksimali vidinė kaina" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Didžiausia kaina pagal vidinius kainų intervalus" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Mažiausia tiekėjo kaina" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Mažiausia detalės kaina iš išorinių tiekėjų" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Didžiausia tiekėjo kaina" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Didžiausia detalės kaina iš išorinių tiekėjų" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Mažiausia varianto kaina" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Apskaičiuota minimali variantų detalių kaina" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Didžiausia varianto kaina" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Apskaičiuota didžiausia variantų detalių kaina" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimali kaina" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Nepaisyti minimalios kainos" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maksimali kaina" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Nepaisyti maksimalios kainos" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Apskaičiuota bendra minimali kaina" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Apskaičiuota bendra maksimali kaina" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimali pardavimo kaina" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Mažiausia pardavimo kaina pagal kainų intervalus" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Didžiausia pardavimo kaina" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Didžiausia pardavimo kaina pagal kainų intervalus" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Mažiausia pardavimo kaina" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Mažiausia istorinė pardavimo kaina" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Didžiausia pardavimo kaina" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Didžiausia istorinė pardavimo kaina" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Detalė inventorizacijai" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Vienetų skaičius" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Atsargų įrašų skaičius inventorizacijos metu" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Bendras prieinamas atsargų kiekis inventorizacijos metu" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Data" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Inventorizacijos atlikimo data" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimali atsargų kaina" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Apytikslė minimali turimų atsargų kaina" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maksimali atsargų kaina" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Apytikslė maksimali turimų atsargų kaina" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Detalės kainų intervalai pardavimui" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Detalės bandymų šablonas" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Bandymų šablonus galima kurti tik testuojamoms detalėms" -#: part/models.py:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Bandymo pavadinimas" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Įveskite bandymo pavadinimą" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Bandymo raktas" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Supaprastintas bandymo raktas" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Bandymo aprašymas" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Įveskite šio bandymo aprašymą" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Ar šis bandymas įjungtas?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Privalomas" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Ar šį bandymą būtina išlaikyti?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Reikalauja reikšmės" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Reikalauja priedo" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Galimi pasirinkimai šiam bandymui (atskirti kableliais)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM elemento keisti negalima - surinkimas užrakintas" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM elemento keisti negalima - varianto surinkimas užrakintas" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Pasirinkite pirminę detalę" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Pavaldi detalė" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Pasirinkite detalę, naudojamą BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "BOM reikalingas šios detalės kiekis" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Šis BOM elementas yra pasirenkamas" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "BOM nuoroda" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "BOM pastabos" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Kontrolinė suma" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "BOM eilutės kontrolinė suma" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Patvirtinta" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Šis BOM elementas patvirtintas" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Paveldima" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Šį BOM elementą paveldi variantų sąrašai" -#: part/models.py:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Sekamoms detalėms kiekis turi būti sveikasis skaičius" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Turi būti nurodyta pavaldi detalė" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "BOM elemento pakaitalas" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Pagrindinis BOM elementas" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Pakaitinė detalė" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Detalė 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Detalė 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Pasirinkite susijusią detalę" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Pastaba šiam ryšiui" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Toks ryšys jau egzistuoja" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Pagrindinė kategorija" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Pagrindinė detalių kategorija" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Subkategorijos" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Rezultatai" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Rezultatų skaičius, susietas su šiuo šablonu" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Šio atsargų elemento pirkimo valiuta" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Failas nėra paveikslėlis" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Pradinė detalė" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Pasirinkite pradinę detalę kopijavimui" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopijuoti paveikslėlį" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Kopijuoti paveikslėlį iš pradinės detalės" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Kopijuoti BOM" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Kopijuoti parametrus" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Kopijuoti parametrų duomenis iš pradinės detalės" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Kopijuoti pastabas" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Kopijuoti pastabas iš pradinės detalės" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Pradinis atsargų kiekis" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Pradinė atsargų vieta" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Nurodykite pradinę atsargų vietą šiai detalei" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Pasirinkite tiekėją (arba palikite tuščią, jei nenorite nurodyti)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Pasirinkite gamintoją (arba palikite tuščią, jei nenorite nurodyti)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Gamintojo detalės numeris" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Pasirinkta įmonė nėra galiojantis tiekėjas" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Pasirinkta įmonė nėra galiojantis gamintojas" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Detalė su šiuo gamintojo numeriu (MPN) jau egzistuoja" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Tiekėjo detalė su šiuo SKU jau egzistuoja" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategorijos pavadinimas" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Surinkimas" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Atsargos" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Versijos" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Bendros atsargos" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Nepriskirtos atsargos" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Variantų atsargos" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Kopijuoti detalę" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kopijuoti pradinius duomenis iš kitos detalės" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Pradinės atsargos" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Sukurti detalę su pradiniu atsargų kiekiu" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Tiekėjo informacija" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Pridėti pradinę tiekėjo informaciją šiai detalei" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kopijuoti kategorijos parametrus" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Kopijuoti parametrų šablonus iš pasirinktos detalių kategorijos" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Esamas paveikslėlis" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Esamos detalės paveikslėlio failo pavadinimas" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Paveikslėlio failas neegzistuoja" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Patvirtinti visą komplektavimo žiniaraštį" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Galima surinkti" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Mažiausia kaina" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Pakeisti apskaičiuotą mažiausią kainą" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Mažiausios kainos valiuta" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Didžiausia kaina" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Pakeisti apskaičiuotą didžiausią kainą" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Didžiausios kainos valiuta" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Atnaujinti" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Atnaujinti šios detalės kainodarą" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Nepavyko konvertuoti iš nurodytų valiutų į {default_currency}" -#: part/serializers.py:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Pasirinkite pirminį surinkimą" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Pasirinkite komponentinę detalę" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Pasirinkite detalę, iš kurios kopijuoti BOM" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Pašalinti esamus duomenis" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Pašalinti esamus BOM elementus prieš kopijuojant" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Įtraukti paveldėtus" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Įtraukti BOM elementus, paveldėtus iš šabloninių detalių" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Praleisti netinkamas eilutes" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Įjunkite šią parinktį, jei norite praleisti netinkamas eilutes" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Kopijuoti pakaitines detales" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopijuoti pakaitines detales, kai kopijuojami BOM elementai" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Perspėjimas apie mažas atsargas" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Kiekis, kurį reikia priskirti" msgid "Label printing failed" msgstr "Etiketės spausdinimas nepavyko" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Klaida generuojant etiketę į PDF formatą" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Klaida generuojant etiketę į HTML formatą" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Nenurodyta jokių elementų spausdinimui" @@ -7100,7 +7273,7 @@ msgstr "Suteikia vietinį brūkšninių kodų palaikymą" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Pranešimas apie pakeistą detalę" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "Detalei `{part.name}` įvyko `{part_action}` įvykis" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF etikečių spausdintuvas" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Suteikia vidinį palaikymą PDF etikečių spausdinimui" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Derinimo režimas" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Įjungti derinimo režimą - grąžina neapdorotą HTML vietoje PDF" @@ -7500,7 +7673,7 @@ msgstr "Rėmelis" msgid "Print a border around each label" msgstr "Spausdinti rėmelį aplink kiekvieną etiketę" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Gulsčias" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Tik personalo vartotojai gali tvarkyti įskiepius" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Įskiepių diegimas išjungtas" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Įskiepis sėkmingai įdiegtas" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Įskiepis įdiegtas į {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Įskiepis neaptiktas registre" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Įskiepis nėra supakuotas įskiepis" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Įskiepio paketo pavadinimas nerastas" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Tik personalo vartotojai gali tvarkyti įskiepius" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Įskiepių šalinimas išjungtas" -#: plugin/installer.py:341 +#: plugin/installer.py:351 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:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Įskiepis neįdiegtas" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Įskiepio diegimas nerastas" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Įskiepis sėkmingai pašalintas" @@ -7689,21 +7875,21 @@ msgstr "Pakuotės įskiepis" msgid "Plugin" msgstr "Įskiepis" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Autorius nerastas" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Įskiepiui reikalinga bent versija {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Įskiepiui reikalinga ne aukštesnė nei versija {v}" @@ -7884,55 +8070,55 @@ msgstr "Įdiegimas nepatvirtintas" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Pilnas perkrovimas" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Vykdyti pilną įskiepių registro perkrovimą" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Priverstinis perkrovimas" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Priverstinai perkrauti įskiepių registrą, net jei jis jau įkeltas" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Surinkti įskiepius" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Surinkti įskiepius ir įtraukti juos į registrą" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Aktyvuoti įskiepį" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Aktyvuoti šį įskiepį" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Ištrinti konfigūraciją" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Ištrinti įskiepio konfigūraciją iš duomenų bazės" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Elementai" @@ -7948,7 +8134,7 @@ msgstr "Įskiepis nepalaiko etikečių spausdinimo" msgid "Invalid label dimensions" msgstr "Neleistini etiketės matmenys" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Šablonui nepateikti galimi elementai" @@ -7972,152 +8158,156 @@ msgstr "Letter" msgid "Template file with this name already exists" msgstr "Šablono failas tokiu pavadinimu jau egzistuoja" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Šablono pavadinimas" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Šablono aprašymas" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Versijos numeris (didinamas automatiškai)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Pridėti prie modelio spausdinant" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Failo vardo šablonas" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Šablonas failų vardų generavimui" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Šablonas įjungtas" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Šablonui skirtas modelio tipas" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtrai" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Šablono failas" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Puslapio dydis PDF ataskaitoms" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Rodyti ataskaitą gulsčiai" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Ataskaita sugeneruota iš šablono {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Klaida generuojant ataskaitą" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Plotis [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Etiketės plotis, nurodytas milimetrais" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Aukštis [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Etiketės aukštis, nurodytas milimetrais" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Klaida spausdinant etiketes" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Fragmentas" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Ataskaitos fragmento failas" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Fragmento failo aprašymas" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Išteklius" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Ataskaitos ištekliaus failas" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Ištekliaus failo aprašymas" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Pasirinkite ataskaitos šabloną" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "Elementų pirminių raktų sąrašas, įtrauktinas į ataskaitą" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Pasirinkite etiketės šabloną" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Spausdinimo įskiepis" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Pasirinkite įskiepį etikečių spausdinimui" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serijos numeris" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Sumontuoti elementai" @@ -8248,184 +8438,196 @@ msgstr "Nėra rezultato (privaloma)" msgid "No result" msgstr "Nėra rezultato" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Ištekliaus failas neegzistuoja" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Paveikslėlio failas nerastas" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "Žyma part_image reikalauja detalės (Part) egzemplioriaus" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "Žyma company_image reikalauja įmonės (Company) egzemplioriaus" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filtruoti pagal vietos gylį" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Filtruoti pagal aukščiausio lygio vietas" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Įtraukti sub-vietas į filtravimo rezultatus" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Pirminė vieta" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtruoti pagal pirminę vietą" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Detalės pavadinimas (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Detalės pavadinimas turi (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Detalės pavadinimas (reguliarioji išraiška)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Detalės IPN (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Detalės IPN turi (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Detalės IPN (reguliarioji išraiška)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Mažiausias kiekis" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Didžiausias kiekis" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Būsenos kodas" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Išorinė vieta" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Sunaudota gamybos užsakyme" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Sumontuota kitame atsargų elemente" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Detalių medis" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Atnaujinta iki" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Atnaujinta po" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Inventorizacija iki" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Inventorizacija po" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Galiojimo data iki" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Galiojimo data po" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Pasenusi" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Reikalingas kiekis" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Turi būti pateikta galiojanti detalė" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Nurodyta tiekėjo detalė neegzistuoja" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Atsargų vietos tipai" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Atsargų vieta" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Atsargų vietos" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Savininkas" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Pasirinkite savininką" @@ -8461,7 +8663,7 @@ msgstr "Pasirinkite savininką" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Išorinė" @@ -8481,274 +8683,282 @@ msgstr "Šios vietos atsargų vietos tipas" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Turi būti nurodyta detalė" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Atsargos negali būti patalpintos į struktūrines atsargų vietas!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Atsargų elementas negali būti sukurtas virtualioms detalėms" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Elementas negali priklausyti pats sau" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Surinkimo nuoroda nenurodo į tą pačią detalę" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Pirminis atsargų elementas" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Pagrindinė detalė" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Pasirinkite atitinkančią tiekėjo detalę šiam atsargų elementui" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Kur yra šis atsargų elementas?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Pakuotė, kurioje laikomas šis atsargų elementas" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Sumontuotas į" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Ar šis elementas yra sumontuotas kitame elemente?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Šio elemento serijos numeris" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Šio atsargų elemento partijos kodas" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Atsargų kiekis" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Surinkimo šaltinis" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Surinkimas šiam atsargų elementui" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Sunaudojo" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Gamybos užsakymas, kuris sunaudojo šį atsargų elementą" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Pirkimo užsakymo šaltinis" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Pirkimo užsakymas šiam atsargų elementui" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Pardavimo užsakymo paskirtis" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Ištrinti išnaudojus" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Ištrinti šį atsargų elementą, kai atsargos bus išnaudotos" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Vieneto pirkimo kaina pirkimo metu" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Konvertuota į detalę" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Detalė nenustatyta kaip sekama" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Kiekis turi būti sveikasis skaičius" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Serijos numeriai turi būti pateikti sąraše" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Kiekis nesutampa su serijos numeriais" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Bandomasis šablonas neegzistuoja" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Atsargų elementas buvo priskirtas pardavimo užsakymui" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Atsargų elementas sumontuotas kitame elemente" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Atsargų elementas turi kitų elementų" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Atsargų elementas buvo priskirtas klientui" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Atsargų elementas šiuo metu gaminamas" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Su serijos numeriais pažymėtų atsargų sujungti negalima" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Pasikartojantys atsargų elementai" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Atsargų elementai turi būti susiję su ta pačia detale" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Atsargų būsenos kodai turi sutapti" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Atsargų elemento sekimas" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Įrašo pastabos" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Atsargų elemento bandymo rezultatas" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Šiam bandymui turi būti pateikta reikšmė" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Šiam bandymui turi būti įkeltas priedas" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Netinkama reikšmė šiam bandymui" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Bandymo rezultatas" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Bandymo išvesties reikšmė" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Bandymo rezultato priedas" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Bandymo pastabos" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Bandymų stotis" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "Bandymų stoties identifikatorius, kurioje atliktas bandymas" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Pradėta" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Bandymo pradžios laiko žyma" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Pabaigta" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Bandymo pabaigos laiko žyma" @@ -8792,246 +9002,246 @@ msgstr "Pasirinkite detalę serijos numeriui sugeneruoti" msgid "Quantity of serial numbers to generate" msgstr "Kiekis serijos numerių, kuriuos reikia sugeneruoti" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Bandymo šablonas šiam rezultatui" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "Turi būti pateiktas šablono ID arba bandymo pavadinimas" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Pirminis elementas" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Pirminis atsargų elementas" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Įveskite serijos numerius naujiems elementams" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Tiekėjo detalės numeris" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Nebegaliojantis" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Antriniai elementai" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Sekami elementai" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Šio atsargų elemento pirkimo kaina, vienetui arba pakuotei" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Įveskite atsargų elementų, kuriuos reikia serializuoti, skaičių" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Kiekis negali viršyti galimų atsargų kiekio ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Paskirties atsargų vieta" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Šiai detalei negali būti priskirti serijos numeriai" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Serijos numeriai jau egzistuoja" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Pasirinkite atsargų elementą montavimui" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Montuojamas kiekis" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Įveskite montuojamų elementų kiekį" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Pridėkite operacijos pastabą (neprivaloma)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Montuojamas kiekis turi būti bent 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Atsargų elementas nepasiekiamas" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Pasirinktos detalės nėra komplektavimo žiniaraštyje" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Montuojamas kiekis negali viršyti turimo kiekio" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Paskirties vieta išmontuotam elementui" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Pasirinkite detalę, į kurią konvertuoti atsargų elementą" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "Pasirinkta detalė netinkama konvertavimui" -#: stock/serializers.py:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Atsargų elemento būsenos kodas" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Pasirinkite atsargų elementus būsenai pakeisti" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Nepasirinkti jokie atsargų elementai" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sub-vietos" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Pirminė atsargų vieta" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Detalė turi būti parduodama" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Elementas priskirtas pardavimo užsakymui" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Elementas priskirtas gamybos užsakymui" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Klientas, kuriam priskiriami atsargų elementai" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Pasirinkta įmonė nėra klientas" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Atsargų priskyrimo pastabos" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Turi būti pateiktas atsargų elementų sąrašas" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Atsargų sujungimo pastabos" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Leisti skirtingus tiekėjus" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Leisti skirtingas būsenas" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Leisti sujungti atsargų elementus su skirtingais būsenos kodais" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Turi būti pateikti bent du atsargų elementai" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Be pakeitimų" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Atsargų elemento pirminio rakto reikšmė" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Atsargų elemento nėra sandėlyje" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Atsargų operacijos pastabos" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Kitas serijos numeris" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Ankstesnis serijos numeris" @@ -9369,227 +9579,247 @@ msgstr "Paskutinis rakto naudojimo laikas" msgid "Revoked" msgstr "Atšauktas" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Leidimų rinkinys" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Peržiūra" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Leidimas peržiūrėti objektus" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Pridėti" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Leidimas pridėti objektus" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Keisti" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Leidimas redaguoti objektus" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Ištrinti" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Leidimas ištrinti objektus" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Botas" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Vidinis" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Svečias" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Kalba" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Pageidaujama vartotojo kalba" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Tema" -#: users/models.py:514 +#: users/models.py:512 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:519 +#: users/models.py:517 msgid "Widgets" msgstr "Valdikliai" -#: users/models.py:521 +#: users/models.py:519 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:528 +#: users/models.py:526 msgid "Display Name" msgstr "Rodomas vardas" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Pasirinktas vartotojo rodomas vardas" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Pareigos" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Pagrindinės pareigos arba darbo pavadinimas" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Vartotojo būsenos žinutė" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Vartotojo buvimo vietos informacija" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "Vartotojas aktyviai naudoja sistemą" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Pageidaujama vartotojo kontaktinė informacija" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Vartotojo tipas" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Kokio tipo tai vartotojas?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organizacija" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Pagrindinė vartotojo organizacija / priklausomybė" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Pagrindinė grupė" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Pagrindinė vartotojo grupė" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administratorius" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Pirkimo užsakymai" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Pardavimo užsakymai" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Grąžinimo užsakymai" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Vartotojo vardas" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Vardas" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Vartotojo vardas" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Pavardė" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Vartotojo pavardė" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Vartotojo el. pašto adresas" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personalas" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Ar šis vartotojas turi personalo leidimus" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Supervartotojas" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Ar šis vartotojas yra supervartotojas" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Ar ši vartotojo paskyra yra aktyvi" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Tik supervartotojas gali keisti šį lauką" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Neturite leidimo kurti vartotojų" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Jūsų paskyra sukurta." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Prisijungimui naudokite slaptažodžio atstatymo funkciją" -#: users/serializers.py:452 +#: users/serializers.py:497 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 84446b5c42..c52edb68aa 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Latvian\n" "Language: lv_LV\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API galapunkts nav atrasts" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Lietotājam nav atļaujas, lai apskatītu šo modeli" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Norādītais daudzums nav derīgs" @@ -112,13 +105,13 @@ msgstr "Ievadiet datumu" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Piezīmes" @@ -131,75 +124,91 @@ msgstr "Vērtība '{name}' neparādās vajadzīgajā formātā" msgid "Provided value does not match required pattern: " msgstr "Norādītā vērtība neatbilst nepieciešamajam formātam: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Tukša sērijas numura rinda" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Atkārtojas sērijas numurs" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Netika atrasts neviens sērijas numurs" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Noņemiet HTML tagus no šīs vērtības" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Savienojuma kļūda" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serveris atbildēja ar nederīgu statusa kodu" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Radās izņēmums" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serveris atbildēja ar nederīgu Content-Length vērtību" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Attēla izmērs ir pārāk liels" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Attēla lejupielāde pārsniedz maksimālo izmēru" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Attālais serveris atgrieza tukšu atbildi" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Norādītajā URL nav derīgs attēla fails" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 62e4bed497..d57e77b082 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API eindpunt niet gevonden" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +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:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Items moeten worden opgegeven als een lijst" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Ongeldige items lijst verstrekt" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filters moeten als woordenboek worden opgegeven" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Ongeldige filters opgegeven" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Alles filteren alleen gebruiken met True" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Geen items die overeenkomen met de opgegeven criteria" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Geen gegevens verstrekt" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Dit veld moet uniek zijn" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Gebruiker heeft geen rechten om dit model te bekijken" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Ongeldige hoeveelheid ingevoerd" @@ -112,13 +105,13 @@ msgstr "Voer datum in" msgid "Invalid decimal value" msgstr "Ongeldige decimale waarde" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Opmerkingen" @@ -131,75 +124,91 @@ msgstr "Waarde '{name}' verschijnt niet in patroonformaat" msgid "Provided value does not match required pattern: " msgstr "Opgegeven waarde komt niet overeen met vereist patroon: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Kan niet meer dan 1000 items tegelijk serienummers geven." -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Leeg serienummer" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplicaat serienummer" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ongeldige groep: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Groepsbereik {group} overschrijdt toegestane hoeveelheid ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Geen serienummers gevonden" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Verwijder HTML tags van deze waarde" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Gegevens bevatten verboden markdown inhoud" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "Ongeldige URL: geen hostnaam" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "Ongeldige URL: hostnaam kon niet worden opgelost" + +#: InvenTree/helpers_model.py:120 +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 +msgid "Too many redirects" +msgstr "Te veel doorverwijzingen" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Verbindingsfout" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Server reageerde met ongeldige statuscode" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Uitzondering opgetreden" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Server reageerde met ongeldige Content-Length waarde" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Afbeeldingsformaat is te groot" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Beelddownload overschrijdt de maximale grootte" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Externe server heeft lege reactie teruggegeven" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Opgegeven URL is geen geldig afbeeldingsbestand" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Schakel tweestapsverificatie in voordat je iets anders kunt doen." @@ -255,133 +264,108 @@ msgstr "Referentie moet overeenkomen met verplicht patroon" msgid "Reference number is too large" msgstr "Referentienummer is te groot" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Ongeldige keuze" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Naam" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Omschrijving" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Omschrijving (optioneel)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Pad" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Dubbele namen kunnen niet bestaan onder hetzelfde bovenliggende object" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown notitie (optioneel)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Streepjescode gegevens" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Streepjescode van derden" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash van Streepjescode" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unieke hash van barcode gegevens" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Bestaande barcode gevonden" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Taak mislukt" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Achtergrondtaak '{f}' is mislukt na {n} pogingen" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverfout" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Er is een fout gelogd door de server." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Moet een geldig nummer zijn" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Selecteer valuta uit beschikbare opties" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Dit veld mag niet nul zijn." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Ongeldige waarde" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Externe afbeelding" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL van extern afbeeldingsbestand" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Afbeeldingen van externe URL downloaden is niet ingeschakeld" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Fout bij het downloaden van afbeelding van externe URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Ongeldig inhoudstype" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Inhoudstype niet gevonden" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Content type komt niet overeen met de vereiste mixin klasse" @@ -537,11 +521,11 @@ msgstr "Chinees (vereenvoudigd)" msgid "Chinese (Traditional)" msgstr "Chinees (traditioneel)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Update beschikbaar" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Een update voor Inventree is beschikbaar" @@ -553,30 +537,30 @@ msgstr "Ongeldige fysieke eenheid" msgid "Not a valid currency code" msgstr "Geen geldige valutacode" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Status van bestelling" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Bovenliggende Productie" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Inclusief varianten" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Inclusief varianten" msgid "Part" msgstr "Onderdeel" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categorie" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Voorouderlijke bouw" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Toegewezen aan mij" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Toegewezen aan" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Gemaakt voor" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Gemaakt na" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Heeft een startdatum" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Vervaldatum voor" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Vervaldatum na" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Heeft doel datum" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Doel datum voor" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Doel datum na" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Voltooid voor" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Voltooid na" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Min. datum" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Max. datum" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Boomstructuur uitsluiten" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Productie moet geannuleerd worden voordat het kan worden verwijderd" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Verbruiksartikelen" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Optioneel" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Samenstelling" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Gevolgd" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testbaar" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Openstaande order" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Toegewezen" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Verbruikt" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "In bestelling" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "Build niet gevonden" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Productieorder" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Locatie" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Uitvoer" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Productieorders" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Assemblage stuklijst is niet gevalideerd" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Bouw bestelling kan niet worden aangemaakt voor een inactief onderdeel" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Maken opdracht kan niet worden gemaakt voor een ontgrendeld onderdeel" -#: build/models.py:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Verantwoorde gebruiker of groep moet worden opgegeven" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Bouworder onderdeel kan niet worden gewijzigd" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Doeldatum moet na startdatum zijn" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Productieorderreferentie" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Productieorderreferentie" msgid "Reference" msgstr "Referentie" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Korte beschrijving van de build (optioneel)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "Productie-opdracht waar dit product aan is toegewezen" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Selecteer onderdeel om te produceren" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Verkooporder Referentie" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Productieopdracht waar dit productie aan is toegewezen" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Bronlocatie" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Externe bouw" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Deze bouw opdracht is extern uitgevoerd" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Bestemmings Locatie" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Selecteer locatie waar de voltooide items zullen worden opgeslagen" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Productiehoeveelheid" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Aantal voorraaditems om te produceren" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Voltooide voorraadartikelen" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Aantal voorraadartikelen die zijn voltooid" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Productiestatus" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Productiestatuscode" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Batchcode" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Batchcode voor deze productieuitvoer" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Aanmaakdatum" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Bouw start datum" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Geplande startdatum voor deze bestelling" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Verwachte opleveringsdatum" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Opleveringsdatum" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "voltooid door" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Uitgegeven door" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Gebruiker die de productieorder heeft gegeven" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Verantwoordelijke" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Gebruiker of groep verantwoordelijk voor deze bouwopdracht" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Externe Link" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link naar externe URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Bouw prioriteit" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioriteit van deze bouwopdracht" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Project code" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Project code voor deze build order" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Kan de bouwopdracht niet voltooien zolang onderliggende bouwopdrachten nog openstaan" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Kan de bouwopdracht niet voltooien zolang de output onvolledig is" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Productieorder {build} is voltooid" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Een productieorder is voltooid" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Serienummers moeten worden opgegeven voor traceerbare onderdelen" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Geen productie uitvoer opgegeven" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Productie uitvoer is al voltooid" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Productuitvoer komt niet overeen met de Productieorder" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Hoeveelheid moet groter zijn dan nul" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Hoeveelheid kan niet groter zijn dan aantal" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "Build output heeft niet alle vereiste tests doorstaan" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "Voorraadproducten zijn nog in productie" -#: build/models.py:1208 +#: build/models.py:1221 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:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Bouw order regel item" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Bouw object" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Hoeveelheid" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Vereiste hoeveelheid voor bouwopdracht" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Aantal van verbruikte voorraad" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Geselecteerde voorraadartikelen komen niet overeen met de BOM-regel" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "Toegewezen hoeveelheid moet groter zijn dan nul" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Hoeveelheid moet 1 zijn voor geserialiseerde voorraad" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Voorraad item is te veel toegewezen" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Voorraadartikel" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Bron voorraadartikel" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Voorraad hoeveelheid toe te wijzen aan productie" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Installeren in" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Bestemming voorraadartikel" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Bouw level" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Onderdeel naam" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Productieuitvoer" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Productieuitvoer komt niet overeen met de bovenliggende productie" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Uitvoeronderdeel komt niet overeen met productieorderonderdeel" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Deze productieuitvoer is al voltooid" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Deze productieuitvoer is niet volledig toegewezen" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Voer hoeveelheid in voor productie uitvoer" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Hoeveelheid als geheel getal vereist voor traceerbare onderdelen" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serienummers" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Voer serienummers in voor productieuitvoeren" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Voorraad locatie voor project uitvoer" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Serienummers automatisch toewijzen" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Vereiste artikelen automatisch toewijzen met overeenkomende serienummers" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "De volgende serienummers bestaan al of zijn ongeldig" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Een lijst van productieuitvoeren moet worden verstrekt" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Voorraadlocatie voor geannuleerde outputs" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Toewijzingen weggooien" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Verwijder alle voorraadtoewijzingen voor geannuleerde outputs" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Reden voor annulering van bouworder(s)" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Locatie van voltooide productieuitvoeren" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Incomplete Toewijzing Accepteren" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Voltooi de uitvoer als de voorraad niet volledig is toegewezen" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Toegewezen voorraad gebruiken" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Verwijder Incomplete Uitvoeren" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Verwijder alle productieuitvoeren die niet zijn voltooid" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Niet toegestaan" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Accepteer zoals geconsumeerd onder deze bouwopdracht" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "De-alloceren voordat deze bouwopdracht voltooid wordt" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Overgealloceerde voorraad" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Sommige voorraadartikelen zijn overalloceerd" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Accepteer Niet-toegewezen" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Vereiste voorraad is niet volledig toegewezen" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Accepteer Onvolledig" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Vereiste productiehoeveelheid is voltooid" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Bouw opdracht heeft open sub bouw orders" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Bouwen moet in de productiestatus staan" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Productieorder heeft onvolledige uitvoeren" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Productielijn" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Productieuitvoer" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Productieuitvoer moet naar dezelfde productie wijzen" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Bouw lijn-item" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Artikel moet op voorraad zijn" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Beschikbare hoeveelheid ({q}) overschreden" -#: build/serializers.py:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Allocaties voor artikelen moeten worden opgegeven" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Locatie uitsluiten" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Voorraadartikelen van deze geselecteerde locatie uitsluiten" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Uitwisselbare voorraad" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Voorraadartikelen op meerdere locaties kunnen uitwisselbaar worden gebruikt" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Vervangende Voorraad" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Toewijzing van vervangende onderdelen toestaan" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Optionele Items" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Alloceer optionele BOM items om bestelling te bouwen" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "Alle artikelen" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "Niet Gevolgde items" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "Gevolgde Items" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "Item Type" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Selecteer item type om automatisch toe te wijzen" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Starten van automatische toewijzing taak mislukt" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "BOM referentie" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "BOM onderdeel ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "BOM onderdeel naam" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "Instaleeren Op" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Bouwen" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Leveranciersonderdeel" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Toegewezen hoeveelheid" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Bouw referentie" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Naam categorie onderdeel" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Volgbaar" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Overgenomen" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Varianten toestaan" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Stuklijstartikel" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "In productie" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Gepland om te bouwen" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Externe voorraad" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Beschikbare Voorraad" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Beschikbare vervanging voorraad" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Beschikbare varianten voorraad" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Verbruikte hoeveelheid overschrijdt toegewezen hoeveelheid" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Optionele notities voor voorraadverbruik" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "Het bouwelement moet verwijzen naar de juiste bouwopdracht" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Dupliceer build item allocatie" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "Build line moet verwijzen naar de juiste bouwopdracht" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Dupliceer build line toewijzing" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Ten minste één item of regel moet worden opgegeven" @@ -1495,43 +1479,47 @@ msgstr "In de wacht" msgid "Cancelled" msgstr "Geannuleerd" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Voltooid" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Voorraad vereist voor productieorder" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Bouw order {build} vereist extra voorraad" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Achterstallige Productieorder" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Productieorder {bo} is nu achterstallig" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Is koppeling" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Is een bestand" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Gebruiker heeft geen toestemming om deze bijlagen te verwijderen" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Gebruiker heeft geen toestemming om deze bijlage te verwijderen." @@ -1551,798 +1539,822 @@ msgstr "Geen geldige valuta codes opgegeven" msgid "No plugin" msgstr "Geen plug-in gevonden" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Projectcode label" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Bijgewerkt" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Tijdstempel van laatste update" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Bijgewerkt door" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Gebruiker die dit object voor het laatst heeft bijgewerkt" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unieke projectcode" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projectbeschrijving" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Instellingen" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Instellingswaarde" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Gekozen waarde is geen geldige optie" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Waarde moet een booleaanse waarde zijn" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Waarde moet een geheel getal zijn" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Waarde moet een geldig getal zijn" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Waarde is niet geldig voor validatiecontrole" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Sleutelreeks moet uniek zijn" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Gebruiker" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Prijs pauze hoeveelheid" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Prijs" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Stukprijs op opgegeven hoeveelheid" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Eindpunt" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Eindpunt waarop deze webhook wordt ontvangen" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Naam van deze webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Actief" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Is deze webhook actief" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Sleutel" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token voor toegang" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Geheim" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Gedeeld geheim voor HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Bericht ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Unieke identificatie voor dit bericht" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Host waarvan dit bericht is ontvangen" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Koptekst" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Koptekst van dit bericht" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Berichtinhoud" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Inhoud van dit bericht" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Eindpunt waarop dit bericht is ontvangen" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Aan gewerkt" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Is het werk aan dit bericht voltooid?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titel" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Koppeling" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Gepubliceerd" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Auteur" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Samenvatting" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Gelezen" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Is dit nieuwsitem gelezen?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Afbeelding" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Doel type voor deze afbeelding" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "Doel modelnummer voor deze afbeelding" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Aangepaste eenheid" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Eenheid symbool moet uniek zijn" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Naam van de unit moet een geldig id zijn" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Naam van eenheid" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbool" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Optionele eenheid symbool" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definitie" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definitie van eenheid" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Bijlage" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Ontbrekend bestand" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Externe link ontbreekt" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Model type" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Doel type voor afbeelding" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Bestand als bijlage selecteren" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Opmerking" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Opmerking van bijlage" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Uploaddatum" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Datum waarop het bestand is geüpload" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Bestandsgrootte" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Bestandsgrootte in bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Ongeldig modeltype opgegeven voor bijlage" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Aangepaste staat" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Aangepaste statussen" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Referentie status set" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Status set die met deze aangepaste status wordt uitgebreid" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logische sleutel" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Waarde" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "De numerieke waarde die wordt opgeslagen in de modellendatabase" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Naam van de toestand" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Label dat in de frontend getoond wordt" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Kleur" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Kleur die in de frontend getoond wordt" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Model met deze staat is gekoppeld aan" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Het model moet worden gekozen" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Sleutel moet worden geselecteerd" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Logische sleutel moet worden geselecteerd" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Sleutel moet anders zijn dan logische sleutel" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Geldige referentie status klasse moet worden opgegeven" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Keuzelijst" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Selectielijst" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Naam van de selectielijst" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Beschrijving van de selectielijst" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Vergrendeld" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Is deze selectielijst vergrendeld?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Kan deze selectielijst worden gebruikt?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Bron plug-in" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Plug-in die de selectielijst biedt" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Bron tekenreeks" -#: common/models.py:2280 +#: common/models.py:2362 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:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Standaard vermelding" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Standaard vermelding voor deze selectielijst" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Gecreëerd" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Datum en tijd waarop de selectielijst is aangemaakt" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Laatst bijgewerkt" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Selectielijst item" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Selectielijst item" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Selectielijst waaraan dit item hoort" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Naam van de selectielijst" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Label voor het item in de selectielijst" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Beschrijving van het item in de selectielijst" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Is dit item in deze lijst actief?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parameter sjabloon" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Parameter sjablonen" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Checkbox parameters kunnen geen eenheden bevatten" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox parameters kunnen geen eenheden bevatten" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Keuzes moeten uniek zijn" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "De template van de parameter moet uniek zijn" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Doelmodeltype voor dit parametersjabloon" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Parameternaam" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Eenheden" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Fysieke eenheden voor deze parameter" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Parameter omschrijving" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Selectievakje" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Is deze parameter een selectievak?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Keuzes" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Geldige keuzes voor deze parameter (komma gescheiden)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Lijst met selecties voor deze parameter" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Ingeschakeld" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Is dit parametersjabloon ingeschakeld?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Parameter" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Parameters" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Ongeldige keuze voor parameter waarde" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Ongeldig modeltype opgegeven voor parameter" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "Model-ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "ID van het doelmodel voor deze parameter" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Sjabloon" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Parameter sjabloon" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Gegevens" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Parameterwaarde" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Opmerking" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Optioneel notities veld" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Barcode Scan" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Barcode gegevens" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Gebruiker die de barcode gescand heeft" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Tijdstempel" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Datum en tijd van de streepjescode scan" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Adres eindpunt dat de streepjescode verwerkt" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Inhoud" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Contextgegevens voor de barcode scan" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Reactie" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Reactiegegevens van de barcode scan" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultaat" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Was de barcode succesvol gescand?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Er is een fout opgetreden" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "E-mailbericht" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "E-mail berichten" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Aangekondigd" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Verzonden" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Mislukt" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Geleverd" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Bevestigd" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Inkomend" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Uitgaand" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Geen antwoord" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Track levering" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Track gelezen" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Track Klik" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Globaal ID" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "Discussie ID" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Gesprek" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Gekoppeld onderwerp voor dit bericht" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Prioriteit" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "E-mail gesprekken" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "E-mail gesprekken" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Sleutel" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Unieke identificatie voor dit bericht" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Intern gestart" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Is dit onderwerp intern gestart?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Datum en tijd waarop de conversatie voor het laatst is bijgewerkt" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Datum en tijd waarop de conversatie voor het laatst is bijgewerkt" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Ontvangen items" @@ -2392,1235 +2404,1303 @@ msgstr "Geeft aan of de instelling overschreven wordt door een omgevingsvariabel msgid "Override" msgstr "Overschrijven" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Is actief" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Openstaande taken" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Geplande taken" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Mislukte taken" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Taak ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Unieke taak ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Vergrendel" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Tijdstip van vergrendeling" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Naam van de taak" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Functie" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Functie naam" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumenten" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Taak argumenten" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Trefwoord argumenten" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Taak trefwoord argumenten" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Bestandsnaam" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Model type" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lijst met selecties is vergrendeld" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Geen groep" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Website URL is vergrendeld door configuratie" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Opnieuw opstarten vereist" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Een instelling is gewijzigd waarvoor een herstart van de server vereist is" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migraties in behandeling" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Aantal nog openstaande database migraties" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Actieve waarschuwingscodes" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Een reeks actieve waarschuwingscodes" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "Instantie Id" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Unieke identificatie voor deze InvenTree instantie" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Aankondiging ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Kondig de instantie ID van de server aan in de server status info (ongeautoriseerd)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "ID Serverinstantie" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Stringbeschrijving voor de server instantie" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Gebruik de instantie naam" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Gebruik de naam van de instantie in de titelbalk" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Tonen `over` beperken" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Toon de `over` modal alleen aan superusers" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "Toon superuser banner" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "Toon een waarschuwings-banner in de UI wanneer ingelogd als superuser" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "Toon admin banner" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "Toon een waarschuwings-banner in de UI wanneer ingelogd als admin" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Bedrijfsnaam" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Interne bedrijfsnaam" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Basis-URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Basis URL voor serverinstantie" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Standaard Valuta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Selecteer basisvaluta voor de berekening van prijzen" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Ondersteunde valuta" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Lijst van ondersteunde valuta codes" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Valuta update interval" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dagen" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Valuta update plug-in" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Munteenheid update plug-in om te gebruiken" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Download van URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Download van afbeeldingen en bestanden vanaf een externe URL toestaan" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Download limiet" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maximale downloadgrootte voor externe afbeelding" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-agent gebruikt om te downloaden van URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Sta toe om de user-agent te overschrijven die gebruikt wordt om afbeeldingen en bestanden van externe URL te downloaden (laat leeg voor de standaard)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Strikte URL validatie" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Vereis schema specificatie bij het valideren van URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Interval voor update" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Hoe vaak te controleren op updates (nul om uit te schakelen)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatische backup" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Automatische back-up van database- en mediabestanden inschakelen" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automatische backup interval" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Geef het aantal dagen op tussen geautomatiseerde backup" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Interval Taak Verwijderen" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Resultaten van achtergrondtaken worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Error Log Verwijderings Interval" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Resultaten van achtergrondtaken worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Interval Verwijderen Notificatie" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Meldingen van gebruikers worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "E-mail verwijderen interval" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "E-mailberichten zullen worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Bescherm e-maillogboeken" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Voorkom het verwijderen van e-mail logs" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Streepjescodeondersteuning" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Schakel barcodescanner ondersteuning in in de webinterface" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Sla de resultaten van de barcode op" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Sla de barcode scan resultaten op in de database" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maximale aantal Barcode Scans" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Maximum aantal resultaten van de barcode scan op te slaan" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Barcode Invoer Vertraging" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Barcode invoerverwerking vertraging" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Barcode Webcam Ondersteuning" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Barcode via webcam scannen in browser toestaan" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Barcode gegevens" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Geef barcode gegevens weer in browser als tekst" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Streepjescode Plug-in" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Plug-in om te gebruiken voor interne barcode data genereren" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Herzieningen onderdeel" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Revisieveld voor onderdeel inschakelen" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Alleen assemblee revisie" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Alleen revisies toestaan voor assemblageonderdelen" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Verwijderen uit Assemblage toestaan" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Regulier expressiepatroon voor het overeenkomende Onderdeel IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Duplicaat IPN toestaan" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Toestaan dat meerdere onderdelen dezelfde IPN gebruiken" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Bewerken IPN toestaan" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Kopieer Onderdeel Stuklijstgegevens" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopieer standaard stuklijstgegevens bij het dupliceren van een onderdeel" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Kopieer Onderdeel Parametergegevens" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Kopieer Onderdeel Testdata" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kopiëer Categorieparameter Sjablonen" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Kopieer categorieparameter sjablonen bij het aanmaken van een onderdeel" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Onderdelen zijn standaard sjablonen" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "Onderdelen kunnen standaard vanuit andere componenten worden samengesteld" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Onderdeel" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Onderdelen kunnen standaard worden gebruikt als subcomponenten" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Koopbaar" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Onderdelen kunnen standaard gekocht worden" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Verkoopbaar" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Onderdelen kunnen standaard verkocht worden" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Onderdelen kunnen standaard gevolgd worden" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtueel" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Onderdelen zijn standaard virtueel" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Verwante onderdelen tonen" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Verwante onderdelen voor een onderdeel tonen" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Initiële voorraadgegevens" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Initiële leveranciergegevens" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Onderdelennaam Weergaveopmaak" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Opmaak om de onderdeelnaam weer te geven" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Standaardicoon voor onderdeel catagorie" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Standaardicoon voor onderdeel catagorie (leeg betekent geen pictogram)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Minimaal aantal prijs decimalen" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Maximum prijs decimalen" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Gebruik leveranciersprijzen" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Prijsvoordelen leveranciers opnemen in de totale prijsberekening" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Aankoopgeschiedenis overschrijven" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historische order prijzen overschrijven de prijzen van de leverancier" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Gebruik voorraaditem prijzen" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Gebruik prijzen van handmatig ingevoerde voorraadgegevens voor prijsberekeningen" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Voorraad artikelprijs leeftijd" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Gebruik variantprijzen" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Variantenprijzen opnemen in de totale prijsberekening" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Alleen actieve varianten" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Gebruik alleen actieve variantonderdelen voor het berekenen van variantprijzen" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Prijzen automatisch bijwerken" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "Automatisch prijzen van onderdelen bijwerken wanneer interne gegevens veranderen" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Prijzen Herbouw interval" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interne Prijzen" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Inschakelen van interne prijzen voor onderdelen" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Interne prijs overschrijven" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "Indien beschikbaar, interne prijzen overschrijven berekeningen van prijsbereik" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "BOM Zero Quantity toestaan" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Printen van labels Inschakelen" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Printen van labels via de webinterface inschakelen" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Label Afbeelding DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Activeer Rapportages" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Activeer het genereren van rapporten" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Foutopsporingsmodus" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Rapporten genereren in debug modus (HTML uitvoer)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Log fouten" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registreer fouten die optreden bij het genereren van rapporten" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Paginagrootte" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Standaard paginagrootte voor PDF rapporten" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forceer Parameter Eenheden" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globaal unieke serienummers" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Serienummers voor voorraaditems moeten globaal uniek zijn" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Verwijder uitgeputte voorraad" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "Bepaalt standaard gedrag wanneer een voorraadartikel leeg is" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Batchcode Sjabloon" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Sjabloon voor het genereren van standaard batchcodes voor voorraadartikelen" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Verlopen Voorraad" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Verlopen voorraad functionaliteit inschakelen" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Verkoop Verlopen Voorraad" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Verkoop verlopen voorraad toestaan" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Voorraad Vervaltijd" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Produceer Verlopen Voorraad" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Sta productie met verlopen voorraad toe" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Voorraad Eigenaar Toezicht" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Eigenaarstoezicht over voorraadlocaties en items inschakelen" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Voorraadlocatie standaard icoon" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Standaard locatie pictogram (leeg betekent geen icoon)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Geïnstalleerde voorraad items weergeven" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Geïnstalleerde voorraadartikelen in voorraadtabellen tonen" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Controleer BOM bij het installeren van items" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Sta 'Niet op voorraad overschrijving' toe" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Productieorderreferentiepatroon" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Vereist patroon voor het genereren van het Bouworderreferentieveld" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Vereis verantwoordelijke eigenaar" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Een verantwoordelijke eigenaar moet worden toegewezen aan elke bestelling" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Vereist een actief onderdeel" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Voorkom het maken van orders voor inactieve onderdelen" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Vergrendeld onderdeel vereisen" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Voorkom het maken van orders voor ontgrendelde onderdelen" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Vereist een geldige BOM" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Onderliggende bestellingen vereist" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Externe Bouw Orders" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Inschakelen externe build order functionaliteit" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blokkeren tot test geslaagd" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Retourorders inschakelen" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Retourorder functionaliteit inschakelen in de gebruikersinterface" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Retourorder referentie patroon" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Verplicht patroon voor het genereren van Retourorder referentie veld" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Bewerk voltooide retourorders" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "Bewerken van retourorders toestaan nadat deze zijn voltooid" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Verkooporderreferentiepatroon" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Vereist patroon voor het genereren van het Verkooporderreferentieveld" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Standaard Verzending Verkooporder" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Aanmaken standaard verzending bij verkooporders inschakelen" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Bewerk voltooide verkooporders" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Zending moet gecontroleerd worden" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "Voorkom voltooiing van verzendingen totdat items zijn gecontroleerd" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Verstuurde bestellingen markeren als voltooid" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Inkooporderreferentiepatroon" -#: common/setting/system.py:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "Vereist patroon voor het genereren van het Inkooporderreferentieveld" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Bewerk voltooide verkooporders" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Valuta converteren" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "Verander artikelwaarde naar basisvaluta bij het ontvangen van voorraad" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Inkooporders automatisch voltooien" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Wachtwoord vergeten functie inschakelen" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Wachtwoord vergeten functie inschakelen op de inlogpagina's" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Registratie inschakelen" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "Zelfregistratie voor gebruikers op de inlogpagina's inschakelen" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSO inschakelen" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "SSO inschakelen op de inlogpagina's" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Schakel gebruikersregistratie met SSO in" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "SSO-groep synchroniseren inschakelen" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO groep sleutel" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSO groep kaart" -#: common/setting/system.py:966 +#: 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 "Een mapping van SSO-groepen naar lokale InvenTree groepen. Als de lokale groep niet bestaat, zal deze worden aangemaakt." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Verwijder groepen buiten SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "E-mailadres verplicht" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Vereis gebruiker om e-mailadres te registreren bij aanmelding" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "SSO-gebruikers automatisch invullen" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Gebruikersdetails van SSO-accountgegevens automatisch invullen" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "E-mail twee keer" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "Bij inschrijving gebruikers twee keer om hun e-mail vragen" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Wachtwoord tweemaal" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Toegestane domeinen" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Inschrijven beperken tot bepaalde domeinen (komma-gescheiden, beginnend met @)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Groep bij aanmelding" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "MFA afdwingen" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Gebruikers moeten multifactor-beveiliging gebruiken." -#: common/setting/system.py:1026 +#: 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 "Het inschakelen van deze instelling zal ervoor zorgen dat alle gebruikers multifactor authenticatie instellen. Alle sessies worden onmiddellijk verbroken." -#: common/setting/system.py:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Controleer plugins bij het opstarten" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Controleren op plug-in updates" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Activeer URL-integratie" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Plugins toestaan om URL-routes toe te voegen" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Activeer navigatie integratie" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Plugins toestaan om te integreren in navigatie" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Activeer app integratie" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Activeer plug-ins om apps toe te voegen" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Activeer planning integratie" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Activeer plugin om periodiek taken uit te voeren" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Activeer evenement integratie" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Activeer plugin om op interne evenementen te reageren" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Interface integratie activeren" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Plug-ins inschakelen om te integreren in de gebruikersinterface" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "E-mail integratie inschakelen" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Schakel plug-ins in om uitgaande / inkomende mails te verwerken" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Activeer project codes" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Schakel projectcodes in voor het bijhouden van projecten" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" -msgstr "" +msgstr "Voorraadcontrole inschakelen" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Externe locaties uitsluiten" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "Voorraadartikelen op externe locaties uitsluiten van voorraadberekeningen" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Automatische Voorraadcontrole Periode" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "Aantal dagen tussen automatische voorraadgegevens opnemen" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "Oude voorraadgegevens verwijderen" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "Voorraadgegevens verwijderen die ouder zijn dan het opgegeven aantal dagen" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "Interval Voorraadgegevens verwijderen" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "Voorraadgegevens zal worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "Oude voorraadgegevens verwijderen" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "Inverval voor verwijderen van voorraadtracking" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Gebruikers volledige namen weergeven" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Laat gebruikers volledige namen zien in plaats van gebruikersnamen" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Gebruikersprofielen tonen" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Toon gebruikersprofielen op hun profielpagina" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Inschakelen van teststation data" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Schakel teststation gegevensverzameling in voor testresultaten" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Machine Ping inschakelen" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 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" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Foutrapportages ontvangen" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Meldingen ontvangen van systeemfouten" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Laatst gebruikte printer" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Alle modellen" @@ -3965,365 +4061,369 @@ msgstr "Onderdeel is actief" msgid "Manufacturer is Active" msgstr "Fabrikant is actief" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Leveranciersonderdelen is actief" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" -msgstr "" +msgstr "Primaire leverancierdeel" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Intern onderdeel is actief" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Leverancier is actief" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabrikant" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Bedrijf" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Heeft voorraad" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Bedrijven" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Bedrijf omschrijving" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Omschrijving van het bedrijf" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Website" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL bedrijfswebsite" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefoonnummer" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Telefoonnummer voor contact" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Contact e-mailadres" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contact" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Contactpunt" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link naar externe bedrijfsinformatie" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Is dit bedrijf actief?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Is klant" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Verkoop je artikelen aan dit bedrijf?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Is leverancier" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Koop je artikelen van dit bedrijf?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Is fabrikant" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Fabriceert dit bedrijf onderdelen?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Standaardvaluta die gebruikt wordt voor dit bedrijf" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "Btw-nr" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "BTW-nummer van bedrijf" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adres" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adres" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Selecteer bedrijf" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Adres titel" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Titel die het adres beschrijft" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Primair adres" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Instellen als primair adres" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Lijn 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adresregel 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Lijn 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adresregel 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Post code" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Plaats/regio" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Postcode plaats/regio" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Staat/provincie" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Staat of provincie" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Land" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adres land" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Koerier verzend notities" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Opmerkingen voor verzending koerier" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Interne verzend notities" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Verzend notities voor intern gebruik" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link naar adres gegevens (extern)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Fabrikant onderdeel" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Basis onderdeel" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Onderdeel selecteren" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Fabrikant selecteren" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "Fabrikant artikel nummer" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Fabrikant artikel nummer (MPN)" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL voor externe link van het fabrikant onderdeel" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Omschrijving onderdeel fabrikant" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Hoeveelheid moet groter zijn dan nul" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Gekoppeld fabrikant onderdeel moet verwijzen naar hetzelfde basis onderdeel" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverancier" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Leverancier selecteren" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Voorraad beheers eenheid voor leveranciers" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Is dit leveranciersdeel actief?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "Primair" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Selecteer fabrikant onderdeel" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL voor link externe leveranciers onderdeel" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Omschrijving leveranciersdeel" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "basisprijs" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimale kosten (bijv. voorraadkosten)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Verpakking" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Onderdeel verpakking" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Pakket hoeveelheid" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "meerdere" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Order meerdere" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Beschikbare hoeveelheid van leverancier" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Beschikbaarheid bijgewerkt" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Datum van de laatste update van de beschikbaarheid gegevens" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Prijsverschil van leverancier" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Standaardvaluta die gebruikt wordt voor deze leverancier" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Bedrijfsnaam" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Op voorraad" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Prijsverschillen" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Fout opgetreden tijdens data export" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Bestaande database-identifier voor het record" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "De kolom is al toegewezen aan een database veld" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Het veld is al toegewezen aan een data-kolom" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "Kolom toewijzing moet worden gekoppeld aan een geldige importsessie" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Kolom bestaat niet in het gegevensbestand" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Veld bestaat niet in het doel model" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Geselecteerde veld is alleen lezen" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Importeer sessie" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Veld" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Kolom" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Rij index" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Oorspronkelijke rij gegevens" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Fouten" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Geldig" -#: importer/models.py:833 +#: 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:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Geen record gevonden met het opgegeven ID" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Ongeldig ID formaat opgegeven" @@ -4588,7 +4688,7 @@ msgstr "Aantal afdrukken voor elk label" msgid "Connected" msgstr "Verbonden" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Onbekend" @@ -4692,7 +4792,7 @@ msgstr "Sleutel van de eigenschap" msgid "Value of the property" msgstr "Waarde van de eigenschap" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Groep" @@ -4720,7 +4820,7 @@ msgstr "Maximale waarde voor voortgangsttype, vereist als type=progress" msgid "Order Reference" msgstr "Order Referentie" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Uitmuntend" @@ -4728,7 +4828,7 @@ msgstr "Uitmuntend" msgid "Has Project Code" msgstr "Heeft een projectcode" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Aangemaakt Door" @@ -4764,57 +4864,69 @@ msgstr "Doel datum voor" msgid "Target Date After" msgstr "Doel datum na" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "Bijgewerkt voor" + +#: order/api.py:236 +msgid "Updated After" +msgstr "Bijgewerkt na" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Heeft prijsstelling" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Voltooid voor" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Voltooid na" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Externe Bouw Opdracht" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Bestellen" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Bestelling voltooid" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Intern onderdeel" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Bestelling in behandeling" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Voltooid" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Heeft verzending" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Inkooporder" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Inkooporder" msgid "Sales Order" msgstr "Verkooporder" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Totaalprijs" msgid "Total price for this order" msgstr "Totaalprijs van deze bestelling" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Valuta bestelling" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,719 +4963,751 @@ msgstr "Valuta voor deze order (laat leeg om de standaard van het bedrijf te geb msgid "This order is locked and cannot be modified" msgstr "Deze bestelling is vergrendeld en kan niet worden gewijzigd" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Contact komt niet overeen met het geselecteerde bedrijf" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Startdatum moet voor einddatum liggen" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "Adres komt niet overeen met het geselecteerde bedrijf" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Bestelling beschrijving (optioneel)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Selecteer projectcode voor deze bestelling" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link naar externe pagina" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Start datum" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Geplande startdatum voor deze bestelling" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Streefdatum" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Datum van uitgifte" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Order uitgegeven op datum" #: order/models.py:506 +msgid "Updated At" +msgstr "Bijgewerkt op" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Gebruiker of groep verantwoordelijk voor deze order" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Contactpunt voor deze volgorde" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Bedrijf adres voor deze bestelling" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Orderreferentie" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Inkooporder status" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Bedrijf waar de artikelen van worden besteld" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Leveranciersreferentie" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Order referentiecode van leverancier" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "ontvangen door" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Order voltooid op datum" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Bestemming" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Bestemming voor ontvangen items" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Onderdeelleverancier moet overeenkomen met de Inkooporderleverancier" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Artikelregel komt niet overeen met inkooporder" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Regelitem mist een gekoppeld deel" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Hoeveelheid moet een positief getal zijn" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klant" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Bedrijf waaraan de artikelen worden verkocht" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Verkooporder status" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Klantreferentie " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Klant order referentiecode" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Verzenddatum" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "verzonden door" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Bestelling is al afgerond" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Order is al geannuleerd" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Alleen een open bestelling kan als voltooid worden gemarkeerd" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "De bestelling is vergrendeld en kan niet worden gewijzigd" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Hoeveelheid artikelen" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Artikelregel referentie" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Artikel notities" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Regelomschrijving (optioneel)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Additionele context voor deze regel" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Stukprijs" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Inkooporder regel item" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Leveranciersonderdeel moet overeenkomen met leverancier" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Bouw bestelling moet worden gemarkeerd als extern" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "Bestellingen kunnen alleen aan assemblageonderdelen worden gekoppeld" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "De bouw van het order deel moet overeenkomen met regel onderdeel" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Leveranciersonderdeel" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Ontvangen" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Aantal ontvangen artikelen" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Inkoopprijs" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Aankoopprijs per stuk" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "Externe Build Order moet aan deze regel voldoen" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Extra regel inkooporder" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Verkooporder regel item" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "Alleen verkoopbare onderdelen kunnen aan een verkooporder worden toegewezen" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Verkoopprijs" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Prijs per stuk" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Verzonden" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Verzonden hoeveelheid" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Verzending van verkooporder" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "Verzendadres moet overeenkomen met de klant" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Verzendadres voor deze zending" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Datum van verzending" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Leveringsdatum" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Datum van levering van zending" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Gecontroleerd door" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Gebruiker die deze zending gecontroleerd heeft" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Zending" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Zendingsnummer" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Volgnummer" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Zending volginformatie" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Factuurnummer" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Referentienummer voor bijbehorende factuur" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Verzending is al verzonden" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Zending heeft geen toegewezen voorraadartikelen" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "Verzending moet worden gecontroleerd voordat deze kan worden voltooid" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Verkooporder extra regel" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Toewijzing verkooporder" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Voorraadartikel is niet toegewezen" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Kan voorraad niet toewijzen aan een regel zonder onderdeel" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Toewijzingshoeveelheid kan niet hoger zijn dan de voorraadhoeveelheid" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Toewijzing hoeveelheid moet groter zijn dan nul" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Hoeveelheid moet 1 zijn voor geserialiseerd voorraadartikel" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Verkooporder komt niet overeen met zending" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Verzending komt niet overeen met verkooporder" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Regel" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Verzendreferentie verkooporder" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Artikel" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Selecteer voorraadartikel om toe te wijzen" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Voer voorraadtoewijzingshoeveelheid in" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Retour order referentie" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Bedrijf van waaruit items worden teruggestuurd" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Retour bestelling status" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Retourneer bestelregel item" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Voorraad item moet worden opgegeven" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Retour hoeveelheid overschrijdt voorraad hoeveelheid" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Het retour aantal moet groter zijn dan nul" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Ongeldige hoeveelheid voor geserialiseerde voorraad" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Selecteer te retourneren product van de klant" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Ontvangst datum" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "De datum waarop dit retour item is ontvangen" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Resultaat" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Resultaat van deze regel item" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Retourneren extra regel" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Bestelling ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID van de bestelling om te dupliceren" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Kopieer regels" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Kopieer regelitems uit de oorspronkelijke bestelling" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Extra regels kopiëren" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Artikelen" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Afgeronde regel items" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Artikel dupliceren" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Specificeer opties voor het dupliceren van deze bestelling" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Ongeldige order ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Leveranciers Naam" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Order kan niet worden geannuleerd" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Toestaan order te sluiten met onvolledige regelitems" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Bestelling heeft onvolledige regelitems" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Order is niet open" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automatisch prijzen" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Koopprijs automatisch berekenen gebaseerd op leveranciers \n" " onderdelen gegevens" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Valuta Inkoopprijs" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Items samenvoegen" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Intern Onderdeelnummer" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Interne naam onderdeel" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Leveranciersonderdeel moet worden gespecificeerd" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Inkooporder moet worden gespecificeerd" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "De leverancier moet overeenkomen met de inkooporder" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Inkooporder moet overeenkomen met de leverancier" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Artikel" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Selecteer bestemmingslocatie voor ontvangen artikelen" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Voer batch code in voor inkomende voorraad items" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Vervaldatum" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Voer vervaldatum in voor inkomende voorraad items" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Voer serienummers in voor inkomende voorraadartikelen" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Overschrijf verpakkingsinformatie voor binnenkomende voorraad" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Extra opmerking voor inkomende voorraad items" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Streepjescode" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Gescande streepjescode" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Streepjescode is al in gebruik" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Artikelen moeten worden opgegeven" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Bestemmingslocatie moet worden opgegeven" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Geleverde streepjescodewaarden moeten uniek zijn" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Verzendingen" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Voltooide Verzendingen" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" -msgstr "" +msgstr "Toegewezen lijnen" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Valuta verkoopprijs" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Toegewezen items" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Geen verzenddetails opgegeven" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Hoeveelheid moet positief zijn" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Voer serienummers in om toe te wijzen" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Verzending is al verzonden" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Zending is niet gekoppeld aan deze bestelling" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Geen overeenkomst gevonden voor de volgende serienummers" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "De volgende serienummers zijn niet beschikbaar" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Retourneer regel item" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Artikelregel komt niet overeen met inkooporder" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Regel item is al ontvangen" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "Artikelen kunnen alleen worden ontvangen tegen lopende bestellingen" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Hoeveelheid te retourneren" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Lijn prijs valuta" @@ -5599,146 +5743,150 @@ msgstr "Restitutie" msgid "Reject" msgstr "Afwijzen" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Achterstallige inkooporder" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Inkooporder {po} is nu achterstallig" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Achterstallige Verkooporder" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Verkooporder {so} is nu achterstallig" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Achterstallige retour orders" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Productieorder {ro} is nu achterstallig" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Favoriet" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filter op categorieën met ster" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Diepte" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filteren op categorie diepte" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Hoogste niveau" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filteren op topniveau categorieën" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Stapelen" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Inclusief subcategorieën in gefilterde resultaten" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Bovenliggend" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filter op bovenliggende categorie" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Subcategorieën uitsluiten in de opgegeven categorie" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Heeft resultaten" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Is een variant" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Is revisie" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Heeft revisies" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "BOM Valid" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Cascade Categorieën" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filter op numerieke categorie-ID of de letterlijke 'null'" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" -msgstr "" +msgstr "Bouw onderdeel is actief" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" -msgstr "" +msgstr "Bouw onderdeel is te volgen" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Assemblage deel is testbaar" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" -msgstr "" +msgstr "Onderdeel is actief" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" -msgstr "" +msgstr "Onderdeel is trackable" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Component onderdeel is testbaar" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" -msgstr "" +msgstr "Onderdeel is nog te bouwen" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" -msgstr "" +msgstr "Onderdeel is virtueel" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" -msgstr "" +msgstr "Heeft beschikbare voorraad" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Gebruik" @@ -5747,11 +5895,11 @@ msgstr "Gebruik" msgid "Part Category" msgstr "Onderdeel Categorie" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Onderdeel Categorieën" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Standaard locatie" @@ -5779,7 +5927,7 @@ msgstr "Standaard trefwoorden voor delen in deze categorie" msgid "Icon" msgstr "Pictogram" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Pictogram (optioneel)" @@ -5800,1025 +5948,1050 @@ msgstr "Standaard waarde" msgid "Default Parameter Value" msgstr "Standaard Parameter Waarde" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Onderdelen" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Kan parameters van een vergrendeld onderdeel niet verwijderen" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Kan de parameters van een vergrendeld onderdeel niet wijzigen" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Kan dit deel niet verwijderen omdat het vergrendeld is" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Kan dit deel niet verwijderen omdat het nog actief is" -#: part/models.py:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN moet overeenkomen met regex patroon {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Onderdeel kan geen herziening van zichzelf zijn" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Kan geen revisie maken van een onderdeel dat al een revisie is" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Revisie code moet worden opgegeven" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Herzieningen zijn alleen toegestaan voor assemblageonderdelen" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Kan geen revisie maken van een sjabloon onderdeel" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Bovenliggend onderdeel moet naar dezelfde sjabloon verwijzen" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Voorraadartikel met dit serienummer bestaat al" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Dubbele IPN niet toegestaan in deelinstellingen" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Dubbele onderdeel revisie bestaat al." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Onderdeel met deze naam, IPN en Revisie bestaat al." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Onderdelen kunnen niet worden toegewezen aan categorieën van structurele onderdelen!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Onderdeel naam" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Is een sjabloon" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Is dit deel van een sjabloon?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Is dit een variant van een ander deel?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variant van" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Beschrijving (optioneel)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Sleutelwoorden" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Deel sleutelwoorden om de zichtbaarheid van de zoekresultaten te verbeteren" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Onderdeel Categorie" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Onderdeel revisie of versienummer" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisie" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Is dit deel een herziening van een ander deel?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Revisie van" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Waar wordt dit item normaal opgeslagen?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Standaard verval datum" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Verlooptijd (in dagen) voor voorraadartikelen van dit deel" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimum voorraad" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimaal toegelaten stock niveau" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Eenheden voor dit onderdeel" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Kan dit onderdeel uit andere delen worden gebouwd?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Kan dit onderdeel gebruikt worden om andere onderdelen te bouwen?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Heeft dit onderdeel een tracking voor unieke items?" -#: part/models.py:1272 +#: part/models.py:1276 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:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Kan dit onderdeel worden gekocht van externe leveranciers?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Kan dit onderdeel aan klanten worden verkocht?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Is dit onderdeel actief?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Vergrendelde onderdelen kunnen niet worden bewerkt" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Stuklijst BOM gecontroleerd" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Is de BOM voor dit deel geldig?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "BOM checksum" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Checksum van BOM opgeslagen" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM gecontroleerd door" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "BOM gecontroleerd datum" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Aanmaken gebruiker" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Eigenaar verantwoordelijk voor dit deel" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Verkopen van meerdere" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Valuta die gebruikt wordt voor de cache berekeningen" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimale BOM kosten" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minimale kosten van onderdelen" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maximale BOM kosten" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maximale kosten van onderdelen" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimale aankoop kosten" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimale historische aankoop kosten" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maximale aanschaf kosten" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maximum historische aankoop kosten" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimale interne prijs" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimale kosten op basis van interne prijsschommelingen" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maximale interne prijs" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maximale kosten gebaseerd op interne prijsvoordelen" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimale leverancier prijs" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Minimale prijs van onderdeel van externe leveranciers" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maximale leverancier prijs" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maximale prijs van onderdeel van externe leveranciers" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimale variant kosten" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Berekende minimale kosten van variant onderdelen" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maximale variant kosten" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Berekende maximale kosten van variant onderdelen" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimale kostprijs" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Overschrijf minimale kosten" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maximale kosten" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Overschrijf maximale kosten" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Berekende minimale kosten" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Berekende totale maximale kosten" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimale verkoop prijs" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Minimale verkoopprijs gebaseerd op prijsschommelingen" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maximale verkoop prijs" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maximale verkoopprijs gebaseerd op prijsschommelingen" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimale verkoop prijs" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimale historische verkoop prijs" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maximale verkoop prijs" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maximale historische verkoop prijs" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Onderdeel voor voorraadcontrole" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Getelde items" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Aantal individuele voorraadvermeldingen op het moment van voorraadcontrole" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Totale voorraad op het moment van voorraadcontrole" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Datum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Datum waarop voorraad werd uitgevoerd" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimale voorraadprijs" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Geschatte minimum kosten van de voorraad op de hand" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maximale voorraadkosten" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Geschatte maximale kosten van de hand van voorraad" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Periodieke verkoopprijs voor onderdelen" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Sjabloon test onderdeel" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Ongeldige sjabloonnaam - moet minstens één alfanumeriek teken bevatten" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Test sjablonen kunnen alleen worden gemaakt voor testbare onderdelen" -#: part/models.py:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Test naam" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Geef een naam op voor de test" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Test sleutel" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Vereenvoudigde sleutel voor de test" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Test beschrijving" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Voer beschrijving in voor deze test" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Is deze test ingeschakeld?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Vereist" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Is deze test nodig om te doorlopen?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Waarde vereist" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Vereist bijlage" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Geldige keuzes voor deze parameter (komma gescheiden)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM item kan niet worden gewijzigd - assemblage is vergrendeld " -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM item kan niet worden gewijzigd - assemblage is vergrendeld" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Selecteer boven liggend onderdeel" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sub onderdeel" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Selecteer onderdeel dat moet worden gebruikt in BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "BOM hoeveelheid voor dit BOM item" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Dit BOM item is optioneel" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Totale hoeveelheid" -#: part/models.py:4014 +#: part/models.py:4091 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:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Attriatie" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Afronden meerdere" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Artikelregel referentie" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "BOM item notities" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Controle som" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "BOM lijn controle som" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Goedgekeurd" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Dit BOM item is goedgekeurd" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Wordt overgenomen" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Hoeveelheid moet een geheel getal zijn voor trackable onderdelen" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Onderdeel moet gespecificeerd worden" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "BOM Item vervangingen bewerken" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "Vervanging onderdeel kan niet hetzelfde zijn als het hoofddeel" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Bovenliggend BOM item" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Vervanging onderdeel" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Eerste deel" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Tweede deel" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Selecteer gerelateerd onderdeel" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Opmerking voor deze relatie" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Dubbele relatie bestaat al" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Bovenliggende categorie" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Bovenliggende onderdeel categorie" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Subcategorieën" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Resultaten" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Aantal resultaten opgenomen ten opzichte van deze template" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Inkooporder voor dit voorraadartikel" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Bestand is geen afbeelding" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Oorspronkelijk onderdeel" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Selecteer origineel onderdeel om te dupliceren" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Afbeelding kopiëren" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Afbeelding kopiëren van het oorspronkelijke onderdeel" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copy BOM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Kopieer materiaal van het oorspronkelijke deel" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Parameters kopiëren" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Parameter data kopiëren van het originele onderdeel" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Notities kopiëren" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Kopieer notities van het originele deel" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Tests kopiëren" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "Test sjablonen kopiëren van het originele deel" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Eerste voorraad hoeveelheid" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Eerste voorraad locatie" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Specificeer locatie van de eerste voorraad voor dit onderdeel" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Selecteer leverancier (of laat leeg om niets in te vullen)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Selecteer fabrikant (of laat leeg om niets in te vullen)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Fabrikant artikel nummer" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Geselecteerde onderneming is geen geldige leverancier" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Geselecteerde bedrijf is geen geldige fabrikant" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Fabrikant deel dat overeenkomt met deze MPN bestaat al" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Leveranciersdeel dat overeenkomt met deze SKU bestaat al" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Categorie naam" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Bouwen" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Hoeveelheid van dit deel dat momenteel in productie is" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Er zal een onuitputtelijke hoeveelheid van dit deel worden gebouwd" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Voorraadartikelen" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revisies" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Totale Voorraad" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Niet toegewezen voorraad" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Variant voorraad" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Dupliceer onderdeel" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kopieer eerste gegevens uit een ander onderdeel" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Eerste voorraad" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Maak onderdeel met eerste voorraad" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Leveranciersgegevens" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Aanvankelijke leveranciersinformatie voor dit deel toevoegen" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Categorie parameters kopiëren" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Parameter sjablonen kopiëren uit geselecteerde onderdeel categorie" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Bestaande afbeelding" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Bestandsnaam van een bestaande onderdeel afbeelding" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Afbeeldingsbestand bestaat niet" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Valideer de gehele materiaalbon" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Kan bouwen" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Vereist voor bouworders" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Toegewezen aan bouwen van orders" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Vereist voor verkooporders" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Toegewezen aan verkooporders" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" -msgstr "" +msgstr "IPN onderdeel" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "Onderdeel omschrijving" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" -msgstr "" +msgstr "Rapport Maken" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimale prijs" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Overschrijf berekende waarde voor minimale prijs" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Minimale prijs valuta" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maximale prijs" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Overschrijf de berekende waarde voor de maximale prijs" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Maximale prijs valuta" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Bijwerken" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Prijzen voor dit onderdeel bijwerken" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Minimumprijs mag niet hoger zijn dan de maximale prijs" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Maximale prijs mag niet lager zijn dan de minimale prijs" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Selecteer de bovenliggende assemblage" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Selecteer het onderdeel" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Selecteer onderdeel om BOM van te kopiëren" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Bestaande gegevens verwijderen" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Verwijder bestaande BOM items voor het kopiëren" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Inclusief overgenomen" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Inclusief stuklijst BOM items die worden overgenomen van getemplated onderdelen" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Ongeldige regels overslaan" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Schakel deze optie in om ongeldige rijen over te slaan" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Verwijder vervangend deel" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopieer vervangende onderdelen bij dubbele stuklijst BOM items" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Lage voorraad melding" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Lage voorraad melding" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "U heeft 1 voorraad product dat de vervaldatum nadert" -#: part/tasks.py:79 +#: part/tasks.py:80 #, 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:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Geen vervaldatum" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} dagen geleden" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Verloopt vandaag" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dagen" @@ -7032,15 +7205,15 @@ msgstr "Toe te wijzen hoeveelheid" msgid "Label printing failed" msgstr "Label afdrukken mislukt" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Fout bij het renderen label naar PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Fout bij het renderen van label naar HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Geen producten aangeboden om af te drukken" @@ -7101,7 +7274,7 @@ msgstr "Biedt ondersteuning voor barcodes" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7447,20 +7620,20 @@ msgstr "Melding gewijzigd onderdeel" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "Het deel `{part.name}` is geactiveerd met een `{part_action}` event" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF label printer" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Biedt ondersteuning voor het drukken van PDF labels" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Foutopsporing modus" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Schakel debug modus in - retourneert ruwe HTML in plaats van PDF" @@ -7501,7 +7674,7 @@ msgstr "Rand" msgid "Print a border around each label" msgstr "Print een rand rond elk label" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Liggend" @@ -7581,64 +7754,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Alleen medewerker gebruikers kunnen plug-ins beheren" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Plug-in installatie is uitgeschakeld" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plug-in succesvol geïnstalleerd" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plug-in geïnstalleerd in {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "De plug-in is niet gevonden in het register" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "De plug-in is geen verpakte plug-in" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Naam van plug-in pakket niet gevonden" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Alleen medewerker gebruikers kunnen plug-ins beheren" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Verwijderen van plug-in is uitgeschakeld" -#: plugin/installer.py:341 +#: plugin/installer.py:351 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:347 +#: plugin/installer.py:357 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:352 +#: plugin/installer.py:362 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:357 +#: plugin/installer.py:367 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:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "De plug-in is niet geïnstalleerd" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Plug-in installatie niet gevonden" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Deïnstalleerde plug-in succesvol" @@ -7690,21 +7876,21 @@ msgstr "Pakket plug-in" msgid "Plugin" msgstr "Plug-in" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Geen auteur gevonden" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "De plug-in vereist minimaal versie {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plug-in vereist op de hoogste versie {v}" @@ -7885,55 +8071,55 @@ msgstr "Installatie niet bevestigd" msgid "Either packagename or URL must be provided" msgstr "Ofwel de pakketnaam van de URL moet worden opgegeven" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Volledige herladen" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Herlaad het plug-in register volledig" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Herladen forceren" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Forceer herladen van het plug-in register, zelfs als het al geladen is" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Plug-ins ophalen" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Verzamel plug-ins en voeg ze toe aan het register" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Activeer plug-in" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Deze plug-in activeren" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Verplichte plug-in kan niet worden gedeactiveerd" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Configuratie verwijderen" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Verwijder de plug-in configuratie uit de database" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "De gebruiker waarvoor deze instelling van toepassing is" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Items" @@ -7949,7 +8135,7 @@ msgstr "Plug-in ondersteunt geen label printen" msgid "Invalid label dimensions" msgstr "Ongeldige label afmetingen" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Geen geldige items aan de template verstrekt" @@ -7973,152 +8159,156 @@ msgstr "Brief" msgid "Template file with this name already exists" msgstr "Sjabloonbestand met deze naam bestaat al" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Template naam" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Template beschrijving" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Revisie nummer (auto verhogen)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Bevestig aan het model bij afdrukken" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Bestandsnaam Patroon" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Patroon voor het genereren van bestandsnamen" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Template is ingeschakeld" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Doel type model voor sjabloon" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filters" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Sjabloon bestand" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Standaard paginagrootte voor PDF rapport" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Rapportage weergeven in liggende stand" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Samenvoegen" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Geef een enkel rapport tegen geselecteerde items" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Rapport gegenereerd door template {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Sjabloon syntaxis fout" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Fout bij het renderen rapport" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Fout bij genereren rapport" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Fout bij samenvoegen rapport uitvoer" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Breedte [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Label breedte, gespecificeerd in mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Hoogte [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Label hoogte, gespecificeerd in mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Fout afdrukken van labels" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Tekstfragment" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Rapporteer snippet bestand" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Snippet bestandsbeschrijving" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Asset" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Rapporteer asset bestand" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Beschrijving asset bestand" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Selecteer rapport template" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 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:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Selecteer label sjabloon" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Plug-in printen" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Selecteer de plug-in voor het afdrukken van labels" @@ -8191,7 +8381,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8216,7 +8406,7 @@ msgstr "Rapport voorraadcontrole" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Geïnstalleerde items" @@ -8249,186 +8439,198 @@ msgstr "Geen resultaat (verplicht)" msgid "No result" msgstr "Geen resultaat" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Asset bestand bestaat niet" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Afbeelding bestand niet gevonden" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image tag vereist een onderdeel instantie" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "bedrijf_imagetag vereist een bedrijfsinstantie" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filter op locatie diepte" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Filter op topniveau locaties" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Inclusief sublocaties in gefilterde resultaten" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Bovenliggende locatie" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filter op bovenliggende locatie" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Naam van onderdeel (hoofdletter ongevoelig)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Naam van onderdeel bevat (hoofdletter ongevoelig)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Naam onderdeel (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Deel IPN (hoofdletter ongevoelig)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Onderdeel IPN bevat (hoofdletter ongevoelig)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Deel IPN (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Minimale voorraad" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Maximale voorraad" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Status code" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Externe locatie" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Verbruikt door productieorder" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Geïnstalleerd in een ander voorraadartikel" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Boomstructuur onderdeel" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Eerder bijgewerkt" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Bijgewerkt na" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Voorraadcontrole voor" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Voorraadcontrole na" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Vervaldatum voor" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Vervaldatum na" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Verouderd" -#: stock/api.py:963 +#: 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:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "Cascade locaties" -#: stock/api.py:982 +#: stock/api.py:981 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:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Filter op numerieke locatie ID of de letterlijke 'null'" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Hoeveelheid is vereist" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Geldig onderdeel moet worden opgegeven" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Het opgegeven leveranciers onderdeel bestaat niet" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "Inclusief geïnstalleerde" -#: stock/api.py:1403 +#: stock/api.py:1411 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:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "Filter op numerieke voorraadartikel ID" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Voorraadartikel met ID {id} bestaat niet" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" -msgstr "" +msgstr "Inclusief Onderdeel varianten" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" -msgstr "" +msgstr "Datum na" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" -msgstr "" +msgstr "Datum voor" #: stock/models.py:73 msgid "Stock Location type" @@ -8442,19 +8644,19 @@ msgstr "Voorraad locatie soorten" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Voorraadlocatie" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Voorraadlocaties" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Eigenaar" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Selecteer eigenaar" @@ -8462,7 +8664,7 @@ msgstr "Selecteer eigenaar" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Extern" @@ -8482,274 +8684,282 @@ msgstr "Voorraad locatie type van deze locatie" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} bestaat niet" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Onderdeel moet gespecificeerd worden" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Voorraaditems kunnen niet worden geplaatst in structurele voorraadlocaties!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Voorraadartikel kan niet worden aangemaakt voor virtuele onderdelen" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "Hoeveelheid moet 1 zijn voor item met een serienummer" -#: stock/models.py:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Item kan niet tot zichzelf behoren" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Bouw referentie verwijst niet naar hetzelfde deel object" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Bovenliggend voorraad item" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Basis onderdeel" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Selecteer een leveranciersdeel voor dit voorraadartikel" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Waar bevindt zich dit voorraaditem?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Het verpakken van dit voorraaditem is opgeslagen in" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Geïnstalleerd in" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Is dit item geïnstalleerd in een ander item?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Serienummer van dit item" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Batch code voor dit voorraaditem" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Voorraad hoeveelheid" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Bron Bouw" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Build voor dit voorraaditem" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Verbruikt door" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Bestelling bouwen welke dit voorraadartikel heeft verbruikt" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Inkooporder Bron" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Inkooporder voor dit voorraadartikel" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Bestemming Verkooporder" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Verwijderen bij leegmaken" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Verwijder dit voorraadproduct wanneer de voorraad is leeg" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Enkele eenheidsprijs van de aankoop op het moment van aankoop" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Omgezet tot onderdeel" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "Hoeveelheid overschrijdt beschikbare voorraad" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Onderdeel is niet ingesteld als traceerbaar" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Hoeveelheid moet heel getal zijn" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Serienummers moeten als lijst worden opgegeven" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Hoeveelheid komt niet overeen met serienummers" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "Kan voorraad niet toewijzen aan structurele locatie" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Testsjabloon bestaat niet" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Voorraadartikel is toegewezen aan een verkooporder" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Voorraad item is geïnstalleerd in een ander item" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Voorraadartikel bevat andere producten" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Voorraadartikel is aan een klant toegewezen" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Voorraad item is momenteel in productie" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Geserialiseerde voorraad kan niet worden samengevoegd" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Dupliceer voorraadartikelen" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Voorraadartikelen moeten hetzelfde onderdeel verwijzen" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Voorraadartikelen moeten verwijzen naar dezelfde leveranciersdeel" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "De voorraad statuscodes moeten overeenkomen" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Voorraad item volgen" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Item notities" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Resultaat voorraad test resultaten" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Waarde moet voor deze test worden opgegeven" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Bijlage moet worden geüpload voor deze test" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Ongeldige waarde voor deze test" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Test resultaat" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Test uitvoer waarde" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Test resultaat bijlage" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Test notities" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Test station" -#: stock/models.py:3085 +#: stock/models.py:3111 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:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Gestart" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Het tijdstip van de start test" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Afgerond" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Het tijdstip van de afgeronde test" @@ -8793,246 +9003,246 @@ msgstr "Selecteer onderdeel voor het genereren van het serienummer voor" msgid "Quantity of serial numbers to generate" msgstr "Aantal serienummers om te genereren" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Test template voor dit resultaat" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "Geen overeenkomende test gevonden voor dit onderdeel" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "SjabloonID of testnaam moet worden opgegeven" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Bovenliggend Item" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Bovenliggende voorraad item" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "Gebruik pakketgrootte" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Voer serienummers voor nieuwe items in" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Leverancier artikelnummer" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Verlopen" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Onderliggende items" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Items volgen" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Inkoopprijs van dit voorraadartikel, per eenheid of pakket" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Aantal voorraaditems om serienummers voor te maken" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "Geen voorraad item opgegeven" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Locatie van bestemming" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Serienummers kunnen niet worden toegewezen aan dit deel" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Serienummers bestaan al" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Selecteer voorraaditem om te installeren" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Te installeren hoeveelheid" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Voer de te installeren hoeveelheid items in" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Transactienotitie toevoegen (optioneel)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Te installeren hoeveelheid moet minimaal 1 zijn" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Voorraadartikel is niet beschikbaar" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Het geselecteerde deel zit niet in de materialen lijst" -#: stock/serializers.py:858 +#: stock/serializers.py:883 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:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Bestemmingslocatie voor verwijderd item" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Selecteer onderdeel om voorraaditem om te zetten in" -#: stock/serializers.py:944 +#: 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:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "Kan voorraadartikel niet converteren met toegewezen leverancier deel" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Voorraad status code" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Selecteer voorraadartikelen om status te wijzigen" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Geen voorraaditems geselecteerd" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sublocaties" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Bovenliggende voorraad locatie" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Onderdeel moet verkoopbaar zijn" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Artikel is toegewezen aan een verkooporder" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Artikel is toegewezen aan een productieorder" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Klant om voorraadartikelen toe te wijzen" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Geselecteerde bedrijf is geen klant" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Voorraad toewijzing notities" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Een lijst met voorraad artikelen moet worden opgegeven" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Voorraad samenvoegen notities" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Niet overeen komende leveranciers toestaan" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Toestaan dat voorraadartikelen met verschillende leveranciers onderdelen worden samengevoegd" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Sta onjuiste status toe" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Toestaan dat voorraadartikelen met verschillende statuscodes worden samengevoegd" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Er moeten ten minste twee voorraadartikelen worden opgegeven" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Geen wijziging" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Voorraaditem primaire sleutel waarde" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Voorraad artikel is niet op voorraad" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "Voorraad artikel is al in voorraad" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "Hoeveelheid mag niet negatief zijn" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Voorraad transactie notities" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "Samenvoegen in bestaande voorraad" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "Voeg indien mogelijk geretourneerde items samen in bestaande voorraad" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Volgend serienummer" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Vorig serienummer" @@ -9370,227 +9580,247 @@ msgstr "Laatste keer dat het token werd gebruikt" msgid "Revoked" msgstr "Intrekken" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Toestemming set" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Weergeven" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Machtiging om items te bekijken" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Toevoegen" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Machtiging om items toe te voegen" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Wijzigen" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Machtigingen om items te bewerken" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Verwijderen" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Toestemming om items te verwijderen" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Bot" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Intern" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Gast" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Taal" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Voorkeurstaal voor gebruiker" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Thema" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Instellingen voor webinterface als JSON - niet handmatig bewerken!" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "Widget" -#: users/models.py:521 +#: users/models.py:519 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:528 +#: users/models.py:526 msgid "Display Name" msgstr "Naam weergeven" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Gekozen weergavenaam voor de gebruiker" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Functie" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Titel of positie hoofdtaken" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Gebruiker status bericht" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Informatie over locatie gebruiker" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "Gebruiker gebruikt actief het systeem" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Voorkeursinformatie voor de gebruiker" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Gebruikers type" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Welk type gebruiker is dit?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organisatie" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Gebruikers primaire organisatie/affiliatie" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Primaire groep" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Primaire groep van de gebruiker" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administrator" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Inkooporders" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Verkooporders" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Retour orders" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Gebruikersnaam" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Voornaam :" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Voornaam van de gebruiker" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Achternaam" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Achternaam van de gebruiker" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "E-mailadres van de gebruiker" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Medewerkers" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Heeft deze gebruiker medewerker machtigingen" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Administrator " -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Is deze gebruiker een administrator " -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Is dit gebruikersaccount actief" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Enkel een supergebruiker kan dit veld aanpassen" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Wachtwoord" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Wachtwoord voor de gebruiker" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Overschrijf waarschuwing" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Overschrijf de waarschuwing over wachtwoord regels" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "U hebt geen toestemming om gebruikers aan te maken" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Je account is aangemaakt." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Gebruik de wachtwoordreset functie om in te loggen" -#: users/serializers.py:452 +#: users/serializers.py:497 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 923e8fadf8..a522c27bd5 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 20:21\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Norwegian\n" "Language: no_NO\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API-endepunkt ikke funnet" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Brukeren har ikke rettigheter til å se denne modellen" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Ugyldig mengde oppgitt" @@ -112,13 +105,13 @@ msgstr "Oppgi dato" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notater" @@ -131,75 +124,91 @@ msgstr "Verdi '{name}' vises ikke i mønsterformat" msgid "Provided value does not match required pattern: " msgstr "Angitt verdi samsvarer ikke med påkrevd mønster: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Tom serienummerstreng" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Duplisert serienummer" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Gruppesekvens {group} overskrider tillatt antall ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Ingen serienummer funnet" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Fjern HTML-tagger fra denne verdien" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Tilkoblingsfeil" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serveren svarte med ugyldig statuskode" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Det har oppstått et unntak" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serveren svarte med ugyldig \"Content-Length\"-verdi" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Bildestørrelsen er for stor" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Bildenedlasting overskred maksimal størrelse" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Ekstern server returnerte tomt svar" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Angitt URL er ikke en gyldig bildefil" @@ -207,11 +216,11 @@ msgstr "Angitt URL er ikke en gyldig bildefil" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-post" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "Referansen må samsvare påkrevd mønster" msgid "Reference number is too large" msgstr "Referansenummeret er for stort" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Ugyldig valg" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Navn" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Beskrivelse" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Beskrivelse (valgfritt)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Sti" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikatnavn kan ikke eksistere under samme overordnede" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown-notater (valgfritt)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Strekkodedata" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Tredjeparts strekkodedata" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Strekkode-hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unik hash av strekkodedata" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Eksisterende strekkode funnet" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverfeil" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "En feil har blitt logget av serveren." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Må være et gyldig tall" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Velg valuta ut fra tilgjengelige alternativer" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Ugyldig verdi" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Eksternt bilde" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URLtil ekstern bildefil" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Nedlasting av bilder fra ekstern URL er ikke aktivert" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kinesisk (forenklet)" msgid "Chinese (Traditional)" msgstr "Kinesisk (tradisjonell)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Ugyldig fysisk enhet" msgid "Not a valid currency code" msgstr "Ikke en gyldig valutakode" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Ordrestatus" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Overordnet produksjon" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategori" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Produksjonen må avbrytes før den kan slettes" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Forbruksvare" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Valgfritt" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Sammenstilling" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Spores" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Tildelt" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "I bestilling" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Produksjonsordre" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Plassering" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Produksjonsordrer" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Sammenstillings-BOMen er ikke godkjent" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Produksjonsordre kan ikke opprettes for en inaktiv del" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Produksjonsordre kan ikke opprettes for en ulåst del" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Ansvarlig bruker eller gruppe må spesifiseres" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Produksjonsordrens del kan ikke endres" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Produksjonsordre-referanse" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Produksjonsordre-referanse" msgid "Reference" msgstr "Referanse" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Kort beskrivelse av produksjonen (valgfritt)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Velg del å produsere" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Salgsordrereferanse" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Kildeplassering" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Fullført plassering" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Velg plassering der fullførte artikler vil bli lagret" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Produksjonsmengde" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Antall lagervarer å produsere" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Fullførte artikler" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Antall lagervarer som er fullført" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Produksjonsstatus" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Produksjonsstatuskode" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Batchkode" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Batchkode for denne produksjonsartikkelen" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Opprettelsesdato" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Forventet sluttdato" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Fullført dato" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "fullført av" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Utstedt av" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Brukeren som utstedte denne produksjonsordren" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarlig" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Bruker eller gruppe ansvarlig for produksjonsordren" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Ekstern lenke" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Lenke til ekstern URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Produksjonsprioritet" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Produksjonsordrens prioritet" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Prosjektkode" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Prosjektkode for denne produksjonsordren" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Produksjonsordre {build} er fullført" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "En produksjonsordre er fullført" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Serienumre må angis for sporbare deler" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Ingen produksjonsartikkel spesifisert" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Produksjonsartikkelen er allerede fullført" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Produksjonsartikkelen samsvarer ikke med produksjonsordren" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Mengden må være større enn null" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Kvantitet kan ikke være større enn utgangsantallet" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Produksjonsartikkel" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Produksjonsobjekt" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antall" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Påkrevd antall for produksjonsordre" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Valgt lagervare samsvarer ikke med BOM-linjen" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Mengden må være 1 for serialisert lagervare" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Lagervaren er overtildelt" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Lagervare" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Kildelagervare" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Lagerantall å tildele til produksjonen" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Monteres i" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Lagervare for montering" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Delnavn" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Produksjonsartikkel" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Produksjonsartikkel samsvarer ikke med overordnet produksjon" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Resultatdel samsvarer ikke med produksjonsordredel" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Denne produksjonsartikkelen er allerede fullført" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Denne produksjonsartikkelen er ikke fullt tildelt" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Angi antall for produksjonsartikkel" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Heltallsverdi kreves for sporbare deler" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Heltallsverdi kreves, da stykklisten inneholder sporbare deler" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Angi serienummer for produksjonsartikler" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Lagerplassering for produksjonsartikkel" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automatisk tildeling av serienummer" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatisk tildeling av nødvendige artikler med tilsvarende serienummer" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Følgende serienummer finnes allerede eller er ugyldige" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "En liste over produksjonsartikler må oppgis" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Lagerplassering for skrotede produksjonsartikler" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Forkast tildelinger" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Forkast tildelinger fra skrotede produksjonsartikler" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Grunn for skroting av produksjonsartikler" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Plassering for ferdige produksjonsartikler" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Godta ufullstendig tildeling" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Fullfør artikler dersom lagerbeholdning ikke er fullt tildelt" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Bruk tildelt lagerbeholdning" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Fjern ufullstendige artikler" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Slett alle produksjonsartikler som ikke er fullført" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Ikke tillatt" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Godta som brukt av denne produksjonsordren" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Fjern tildeling før produksjonsordren fullføres" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Overtildelt lagerbeholdning" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Noen lagervarer har blitt overtildelt" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Godta ikke tildelt" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Nøvendig lagerbeholdning er ikke fullt tildelt" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Godta uferdig" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Nødvendig produksjonsmengde er ikke nådd" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Produksjonsordren har uferdige artikler" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Produksjonslinje" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Produksjonsartikkel" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Produksjonsartikkel må peke til samme produksjon" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Produksjonsartikkel" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Artikkelen må være på lager" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Tilgjengelig antall ({q}) overskredet" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "Produksjonsartikkel må spesifiseres for tildeling av sporede deler" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Produksjonsartikkel kan ikke spesifiseres for tildeling av usporede deler" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Tildelingsartikler må oppgis" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Eksluderer plassering" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Ekskluder lagervarer fra denne valgte plasseringen" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Utskiftbar lagerbeholdning" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Lagervarer ved flere plasseringer kan brukes om hverandre" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Erstatning-lagerbeholdning" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Tilatt tildelling av erstatningsdeler" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Valgfrie artikler" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Tildel valgfrie BOM-artikler til produksjonsordre" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Kunne ikke starte auto-tideling" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "BOM-referanse" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Leverandørdel" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Tildelt antall" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Produksjonsreferanse" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Delkategorinavn" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Sporbar" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Nedarvet" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Tillat Varianter" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "BOM-artikkel" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "I produksjon" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Ekstern lagerbeholdning" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Tilgjengelig lagerbeholdning" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Tilgjengelige erstatningsvarer" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Tilgjengelige variantvarer" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Kansellert" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Fullført" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Lagerbeholdning kreves for produksjonsordre" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Forfalt produksjonsordre" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Produksjonsordre {bo} er nå forfalt" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Er lenke" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Er fil" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Brukeren har ikke tillatelse til å slette dette vedlegget" @@ -1551,798 +1539,822 @@ msgstr "Ingen gyldige valutakoder angitt" msgid "No plugin" msgstr "Ingen programtillegg" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Etikett for prosjektkode" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Oppdatert" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Tidsstempel for forrige oppdatering" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unik prosjektkode" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Prosjektbeskrivelse" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Bruker eller gruppe ansvarlig for dette prosjektet" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Innstillings verdi" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Valgt verdi er ikke et gyldig alternativ" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Verdien må være en boolsk verdi" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Verdien må være et heltall" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Nøkkelstreng må være unik" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Bruker" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Antall for prisbrudd" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Pris" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Enhetspris på spesifisert antall" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Endepunkt" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Endepunktet hvor denne webhooken er mottatt" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Navn for webhooken" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktiv" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Er webhooken aktiv" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Sjetong" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Nøkkel for tilgang" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Hemmelig" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Delt hemmlighet for HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Melding ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Unik Id for denne meldingen" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Vert" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Verten denne meldingen ble mottatt fra" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Tittel" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Overskrift for denne meldingen" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Brødtekst" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Innholdet i meldingen" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Endepunktet meldingen ble mottatt fra" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Arbeidet med" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Var arbeidet med denne meldingen ferdig?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Tittel" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Lenke" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publisert" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Forfatter" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Sammendrag" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Les" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Er dette nyhetselementet lest?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Bildefil" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Enhetssymbolet må være unikt" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Enhetsnavn må være en gyldig identifikator" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Enhetsnavn" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Valgfritt enhetssymbol" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definisjon" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Enhetsdefinisjon" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Vedlegg" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Fil mangler" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Mangler eksternlenke" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Velg fil å legge ved" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Vedleggskommentar" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Opplastet dato" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Datoen som filen ble lastet opp" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Filstørrelse" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Filstørrelse i byte" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Ugyldig modelltype spesifisert for vedlegg" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Verdi" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Opprettet" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Sist oppdatert" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parametermal" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Sjekkboksparameter kan ikke ha enheter" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Sjekkboksparameter kan ikke ha valg" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Valg må være unike" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Navn på parametermal må være unikt" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Parameternavn" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Enheter" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Fysisk enheter for denne parameteren" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Parameterbeskrivelse" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Sjekkboks" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Er dette parameteret en sjekkboks?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Valg" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Gyldige valg for denne parameteren (kommaseparert)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Aktivert" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Ugyldig valg for parameterverdi" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Mal" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Parameterverdi" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Notat" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Valgfritt notatfelt" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultat" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Nøkkel" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Artikler mottatt" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Kjører" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Ventende oppgaver" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Planlagte oppgaver" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Mislykkede oppgaver" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Oppgave-ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Unik oppgave-ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Lås" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Låsetidspunkt" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Oppgavenavn" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funksjon" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funksjonsnavn" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumenter" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Oppgaveargumenter" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Nøkkelordargumenter" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Nøkkelordargumenter for oppgave" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Filnavn" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Modelltype" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Ingen gruppe" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Nettstedets URL er låst av konfigurasjon" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Omstart kreves" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "En innstilling har blitt endret som krever en omstart av serveren" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Ventende migrasjoner" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Antall ventende databasemigreringer" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Navn på serverinstans" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Strengbeskrivelse for serverinstansen" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Bruk instansnavn" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Bruk instansnavnet på tittellinjen" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Begrens visning av 'om'" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Vis `about`-modal kun til superbrukere" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Firmanavn" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Internt firmanavn" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Base-URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Base-URL for serverinstans" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Standardvaluta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Velg grunnvalutaen for prisberegninger" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Støttede valutaer" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Liste over støttede valutakoder" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Oppdateringsintervall for valuta" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dager" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Valutaoppdaterings-plugin" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Valgt valutaoppdaterings-plugin" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Last ned fra URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Tillat nedlastning av eksterne bilder og filer fra ekstern URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Nedlastingsgrense" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maksimal tillatt nedlastingsstørrelse for eksternt bilde" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-Agent brukt for å laste ned fra URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Tillat overstyring av User-Agent brukt for å laste ned bilder og filer fra eksterne URLer (lå stå blank for standard)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Streng URL-validering" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Krev skjemaspesifikasjon ved validering av URLer" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Intervall for oppdateringssjekk" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Tidsintervall for å se etter oppdateringer(sett til null for å skru av)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatisk sikkerhetskopiering" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Aktiver automatisk sikkerhetskopiering av database og mediafiler" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automatisk sikkerhetskopieringsintervall" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Angi antall dager mellom automatiske sikkerhetskopieringshendelser" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Slettingsintervall for oppgaver" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Bakgrunnsoppgaveresultater vil bli slettet etter antall angitte dager" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Slettingsintervall for feillogg" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Feilloggene vil bli slettet etter et angitt antall dager" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Slettingsintervall for varsler" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Brukervarsler slettes etter angitt antall dager" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Strekkodestøtte" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Aktiver støtte for strekkodeleser i webgrensesnittet" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Innlesingsforsinkelse for strekkode" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tidsforsinkelse for behandling av strekkode" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Støtte for strekkodewebkamera" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Tillat strekkodelesning via webkamera i nettleseren" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Vis Strekkodedata" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Vis strekkodedata som tekst" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Delrevisjoner" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Aktiver revisjonsfeltet for Del" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Regulært uttrykksmønster for matching av internt delnummer" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Tilat duplikat av internt delnummer" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Tillat flere deler å dele samme interne delnummer" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Tillat redigering av internt delnummer" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Kopier BOM-data fra del" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Kopier parameterdata fra del" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "Kopier parameterdata som standard ved duplisering av en del" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Kopier testdata fra del" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "Kopier testdata som standard ved duplisering av en del" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kopier designmaler for kategoriparametere" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Kopier parametermaler for kategori ved oppretting av en del" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Deler er maler som standard" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "Deler kan settes sammen fra andre komponenter som standard" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "Deler kan bli brukt som underkomponenter som standard" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Kjøpbar" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Deler er kjøpbare som standard" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Salgbar" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Deler er salgbare som standard" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Deler er sporbare som standard" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuelle" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Deler er virtuelle som standard" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Vis relaterte deler" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Vis relaterte deler i en del" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Innledende lagerbeholdningsdata" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Innledende leverandørdata" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Visningsformat for delnavn" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Format for å vise delnavnet" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Standardikon for delkategorier" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Standardikon for delkategorier (tomt betyr ingen ikon)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Minimum antall desimalplasser for priser" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Maksimalt antall desimalplasser for priser" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Bruk leverandørpriser" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Inkluder leverandørprisbrudd i beregninger av totalpriser" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Innkjøpshistorikkoverstyring" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historiske innkjøpspriser overstyrer leverandørprisnivåer" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Bruk lagervarepriser" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Bruk priser fra manuelt innlagte lagervarer for prisberegninger" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Lagervare prisalder" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Bruk Variantpriser" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Inkluder variantpriser i beregninger av totale priser" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Kun aktive varianter" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Bruk kun aktive variantdeler til beregning av variantprising" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervall for rekalkulering av priser" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "Antall dager før delpriser blir automatisk oppdatert" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interne Priser" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Aktiver interne priser for deler" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Intern prisoverstyring" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "Hvis tilgjengelig, overstyrer interne priser kalkulering av prisområde" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Aktiver etikettutskrift" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Aktiver utskrift av etiketter fra nettleseren" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Etikettbilde-DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Aktiver Rapporter" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Aktiver generering av rapporter" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Feilsøkingsmodus" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Generer rapporter i feilsøkingsmodus (HTML-output)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Sidestørrelse" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Standard sidestørrelse for PDF-rapporter" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Tving parameterenheter" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globalt Unike Serienummer" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Serienummer for lagervarer må være globalt unike" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Slett oppbrukt lagerbeholdning" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Batchkodemal" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Mal for generering av standard batchkoder for lagervarer" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Lagerbeholdning utløper" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Aktiver funksjonalitet for utløp av lagerbeholdning" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Selg utløpt lagerbeholdning" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Tillat salg av utgått lagerbeholdning" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Foreldet lagerbeholdning tidsintervall" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Produsér Utløpt Lagerbeholdning" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Tillat produksjon med utløpt lagerbeholdning" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Kontroll over eierskap av lagerbeholdning" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Aktiver eierskap over lagerplasseringer og -varer" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Lagerplassering standard ikon" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Lagerplassering standard ikon (tomt betyr ingen ikon)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Vis installerte lagervarer" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Vis installerte lagervarer i lagertabeller" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Produksjonsordre-referansemønster" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Nødvendig mønster for å generere Produksjonsordre-referansefeltet" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Aktiver returordrer" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Aktiver returordrefunksjonalitet i brukergrensesnittet" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Returordre-referansemønster" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Rediger fullførte returordrer" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Salgsordre-referansemønster" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Påkrevd mønster for å generere salgsordrereferansefelt" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Salgsordre standard fraktmetode" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Aktiver opprettelse av standard forsendelse med salgsordrer" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Rediger fullførte salgsordrer" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "Referansemønster for innkjøpsordre" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "Obligatorisk mønster for generering av referansefelt for innkjøpsordre" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "Rediger fullførte innkjøpsordre" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Referansemønster for innkjøpsordre" + +#: common/setting/system.py:918 +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 +msgid "Edit Completed Purchase Orders" +msgstr "Rediger fullførte innkjøpsordre" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Autofullfør innkjøpsordrer" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Aktiver passord glemt" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Aktiver registrering" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Aktiver SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Aktiver SSO på innloggingssidene" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Aktiver SSO-registrering" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "E-postadresse kreves" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Krevt at brukere angir e-post ved registrering" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Auto-utfyll SSO-brukere" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Fyll automatisk ut brukeropplysninger fra SSO-kontodata" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "E-post to ganger" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "Spør brukeren om e-post to ganger ved registrering" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Passord to ganger" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "Spør brukeren om passord to ganger ved registrering" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Tillatte domener" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Begrens registrering til bestemte domener (kommaseparert, begynner med @)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Gruppe ved registrering" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Krev MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Brukere må bruke flerfaktorsikkerhet." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Sjekk utvidelser ved oppstart" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Aktiver URL-integrasjon" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Tillat utvidelser å legge til URL-ruter" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Aktiver navigasjonsintegrasjon" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Tillat utvidelser å integrere mot navigasjon" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Aktiver app-integrasjon" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Tillat utvidelser å legge til apper" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Aktiver tidsplanintegrasjon" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Tillat utvidelser å kjøre planlagte oppgaver" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Aktiver hendelsesintegrasjon" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Tillat utvidelser å reagere på interne hendelser" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Ekskluder eksterne plasseringer" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Automatisk varetellingsperiode" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Vis brukernes fulle navn" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Vis brukernes fulle navn istedet for brukernavn" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Motta feilrapporter" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Motta varsler om systemfeil" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Delen er aktiv" msgid "Manufacturer is Active" msgstr "Leverandør er aktiv" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Leverandørdel er aktiv" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Intern del er aktiv" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Leverandør er aktiv" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Produsent" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Firma" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Firmaer" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Beskrivelse av firma" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Beskrivelse av firmaet" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Nettside" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Bedriftens nettside URL" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefonnummer" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Kontakt-telefonnummer" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontakt e-post" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Kontaktpunkt" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link til ekstern bedriftsinformasjon" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Er firmaet aktivt?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Er kunde" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Selger du varer til dette firmaet?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Er leverandør" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Kjøper du varer fra dette firmaet?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Er produsent" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Produserer dette firmaet deler?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Standardvaluta brukt for dette firmaet" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adresse" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adresser" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Velg selskap" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Adressetittel" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Tittel som beskriver addressen" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Hovedadresse" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Sett som hovedadresse" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Linje 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adresselinje 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Linje 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adresselinje 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Postnummer" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Poststed/område" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Postnummerets by/område" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Delstat/provins" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Delstat eller provins" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Land" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adressens land" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notater til transportør" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notater for transportør" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Interne fraktnotater" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Fraktnotater for internt bruk" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Lenke til adresseinformasjon (ekstern)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Produsentdeler" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Basisdel" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Velg del" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Velg produsent" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Produsentens varenummer" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL for ekstern produsentdel-lenke" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Produsentens delbeskrivelse" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "Pakkeenhetene må være komptible med delens basisenhet" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Pakkeenhet må være mer enn null" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Den sammenkoblede produsentdelen må referere til samme basisdel" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverandør" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Velg leverandør" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Leverandørens lagerbeholdningsenhet" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Er denne leverandørdelen aktiv?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Velg produsentdel" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL for ekstern leverandørdel-lenke" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Leverandørens delbeskrivelse" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "grunnkostnad" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimum betaling (f.eks. lageravgift)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Emballasje" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Delemballasje" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Pakkeantall" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "flere" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Bestill flere" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Antall tilgjengelig fra leverandør" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Tilgjengelighet oppdatert" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Dato for siste oppdatering av tilgjengelighetsdata" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Leverandørens prisbrudd" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Standardvaluta brukt for denne leverandøren" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Bedriftsnavn" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "På lager" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Gyldig" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Ukjent" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Gruppe" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Ordrereferanse" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Opprettet av" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Ordre" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Intern del" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Fullført" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Innkjøpsordre" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Innkjøpsordre" msgid "Sales Order" msgstr "Salgsordre" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Total pris" msgid "Total price for this order" msgstr "Total pris for denne ordren" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Ordrevaluta" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta for denne ordren (la stå tom for å bruke firmastandard)" @@ -4851,718 +4963,750 @@ msgstr "Valuta for denne ordren (la stå tom for å bruke firmastandard)" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Kontakten samsvarer ikke med valgt firma" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Ordrebeskrivelse (valgfritt)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Velg prosjektkode for denne ordren" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Lenke til ekstern side" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Måldato" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Sendt dato" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Dato bestillingen ble sendt" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Bruker eller gruppe ansvarlig for ordren" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Kontaktpunkt for denne ordren" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Selskapsadresse for denne ordren" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Ordrereferanse" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Status for innkjøpsordre" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Firma som varene blir bestilt fra" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Leverandørreferanse" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Leverandørens ordrereferanse" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "mottatt av" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Dato ordre ble fullført" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destinasjon" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Delleverandør må matche PO-leverandør" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Linjeelementet samsvarer ikke med innkjøpsordre" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Mengde må være positiv" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kunde" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Firma som varene selges til" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Kundereferanse " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Kundens ordrereferanse" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Forsendelsesdato" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "sendt av" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Kun en åpen ordre kan merkes som fullført" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Bestillingen kan ikke fullføres da det finnes ufullstendige forsendelser" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Antall" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Linjereferanse" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Linjenotater" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Linjeelementbeskrivelse (valgfritt)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Ytterligere kontekst for denne linjen" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Enhetspris" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Delens leverandør må samsvare med leverandør" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Leverandørdel" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Mottatt" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Antall enheter mottatt" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Innkjøpspris" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Enhet-innkjøpspris" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "Kun salgbare deler kan tildeles en salgsordre" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Salgspris" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Enhets-salgspris" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Sendt" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Sendt antall" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Dato for forsendelse" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Leveringsdato" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Dato for levering av forsendelse" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Sjekket Av" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Brukeren som sjekket forsendelsen" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Forsendelse" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Forsendelsesnummer" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Sporingsnummer" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Sporingsinformasjon for forsendelse" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Fakturanummer" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Referansenummer for tilknyttet faktura" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Forsendelsen er allerede sendt" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Forsendelsen har ingen tildelte lagervarer" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Lagervarer er ikke blitt tildelt" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Kan ikke tildele lagerbeholdning til en linje uten en del" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Tildelingsantall kan ikke overstige tilgjengelig lagerbeholdning" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Tildelingsantall må være større enn null" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Antall må være 1 for serialisert lagervare" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Salgsordre samsvarer ikke med forsendelse" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Forsendelsen samsvarer ikke med salgsordre" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Linje" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Forsendelsesreferanse for salgsordre" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Artikkel" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Velg lagervare å tildele" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Angi lagertildelingsmengde" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Returordre-referanse" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Firmaet delen skal returneres fra" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Returordrestatus" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Velg artikkel som skal returneres fra kunde" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Mottatt Dato" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Utfall" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Utfall for dette linjeelementet" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "Kostnad forbundet med retur eller reparasjon for dette linjeelementet" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Linjeelementer" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Leverandørnavn" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Ordren kan ikke kanselleres" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Tillat ordre å lukkes med ufullstendige linjeelementer" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Ordren har ufullstendige linjeelementer" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Ordren er ikke åpen" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Innkjøpsvaluta" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU-kode" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Internt delnummer" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Leverandørdel må angis" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Innkjøpsordre må angis" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Leverandør må samsvare med innkjøpsordre" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Innkjøpsordre må samsvare med leverandør" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Ordrelinje" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Velg lagerplassering for mottatte enheter" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Angi batchkode for innkommende lagervarer" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Utløpsdato" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Angi serienummer for innkommende lagervarer" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Strekkode" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Skannet strekkode" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Strekkode allerede i bruk" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Linjeelementer må være oppgitt" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Målplassering må angis" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Angitte strekkodeverdier må være unike" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Fullførte forsendelser" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Valuta for salgspris" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Ingen forsendelsesopplysninger oppgitt" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Mengden må være positiv" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Skriv inn serienummer for å tildele" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Forsendelsen er allerede sendt" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Forsendelsen er ikke knyttet til denne ordren" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Ingen treff funnet for følgende serienummer" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Returordrelinje" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Linjeelementet samsvarer ikke med returordre" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Linjeelementet er allerede mottatt" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Valuta for linje" @@ -5598,146 +5742,150 @@ msgstr "Refusjon" msgid "Reject" msgstr "Avvis" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Forfalt Innkjøpsordre" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Innkjøpsordre {po} er nå forfalt" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Forfalt Salgsordre" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Salgsordre {so} er nå forfalt" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Delkategori" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Delkategorier" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Standard plassering" @@ -5778,7 +5926,7 @@ msgstr "Standard nøkkelord for deler i denne kategorien" msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikon (valgfritt)" @@ -5799,1025 +5947,1050 @@ msgstr "Standardverdi" msgid "Default Parameter Value" msgstr "Standard Parameterverdi" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Deler" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN må samsvare med regex-mønsteret {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Lagervare med dette serienummeret eksisterer allerede" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplikat av internt delnummer er ikke tillatt i delinnstillinger" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Del med dette Navnet, internt delnummer og Revisjon eksisterer allerede." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Deler kan ikke tilordnes strukturelle delkategorier!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Delnavn" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Er Mal" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Er delen en maldel?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Er delen en variant av en annen del?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variant av" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Delbeskrivelse (valgfritt)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Nøkkelord" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Del-nøkkelord for å øke synligheten i søkeresultater" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Delkategori" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Delrevisjon eller versjonsnummer" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisjon" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Hvor er denne artikkelen vanligvis lagret?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Standard utløp" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Utløpstid (i dager) for lagervarer av denne delen" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimal lagerbeholdning" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimum tillatt lagernivå" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Måleenheter for denne delen" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Kan denne delen bygges fra andre deler?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Kan denne delen brukes til å bygge andre deler?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Har denne delen sporing av unike artikler?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Kan denne delen kjøpes inn fra eksterne leverandører?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Kan denne delen selges til kunder?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Er denne delen aktiv?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Kontrollsum for BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Lagret BOM-kontrollsum" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Stykkliste sjekket av" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Stykkliste sjekket dato" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Opprettingsbruker" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Eier ansvarlig for denne delen" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Selg flere" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Valuta som brukes til å bufre prisberegninger" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimal BOM-kostnad" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minste kostnad for komponentdeler" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maksimal BOM-kostnad" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maksimal kostnad for komponentdeler" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimal innkjøpskostnad" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimal historisk innkjøpskostnad" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maksimal innkjøpskostnad" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maksimal historisk innkjøpskostnad" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimal intern pris" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimal kostnad basert på interne prisbrudd" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maksimal intern pris" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maksimal kostnad basert på interne prisbrudd" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimal leverandørpris" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Minimumspris for del fra eksterne leverandører" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maksimal leverandørpris" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maksimalpris for del fra eksterne leverandører" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimal Variantkostnad" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Beregnet minimal kostnad for variantdeler" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maksimal Variantkostnad" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Beregnet maksimal kostnad for variantdeler" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimal kostnad" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Overstyr minstekostnad" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maksimal kostnad" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Overstyr maksimal kostnad" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Beregnet samlet minimal kostnad" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Beregnet samlet maksimal kostnad" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimal salgspris" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Minimal salgspris basert på prisbrudd" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maksimal Salgspris" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maksimal salgspris basert på prisbrudd" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimal Salgskostnad" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimal historisk salgspris" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maksimal Salgskostnad" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maksimal historisk salgspris" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Del for varetelling" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Antall" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Antall individuelle lagerenheter på tidspunkt for varetelling" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Total tilgjengelig lagerbeholdning på tidspunkt for varetelling" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Dato" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Dato for utført lagertelling" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimal lagerkostnad" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Estimert minimal kostnad for lagerbeholdning" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maksimal lagerkostnad" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Estimert maksimal kostnad for lagerbeholdning" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Testnavn" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Angi et navn for testen" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Testbeskrivelse" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Legg inn beskrivelse for denne testen" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Påkrevd" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Er det påkrevd at denne testen bestås?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Krever verdi" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Krever vedlegg" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Velg overordnet del" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Underordnet del" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Velg del som skal brukes i BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "BOM-antall for denne BOM-artikkelen" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Denne BOM-artikkelen er valgfri" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "BOM-artikkelreferanse" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "BOM-artikkelnotater" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Kontrollsum" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "BOM-linje kontrollsum" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Godkjent" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Denne BOM-artikkelen er godkjent" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Arves" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Denne BOM-artikkelen er arvet fra stykkliste for variantdeler" -#: part/models.py:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Antall må være heltallsverdi for sporbare deler" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Underordnet del må angis" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "BOM-artikkel erstatning" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "Erstatningsdel kan ikke være samme som hoveddelen" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Overordnet BOM-artikkel" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Erstatningsdel" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Del 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Del 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Velg relatert del" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Duplikatforhold eksisterer allerede" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Underkategorier" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Innkjøpsvaluta for lagervaren" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Original Del" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Velg original del å duplisere" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopier Bilde" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Kopier bilde fra originaldel" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Kopier Stykkliste" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Kopier stykkliste fra original del" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Kopier parametere" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Kopier parameterdata fra originaldel" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Kopier notater" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Kopier notater fra originaldel" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Innledende lagerbeholdning" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Innledende lagerplassering" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Angi initiell lagerplasering for denne delen" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Velg leverandør (eller la stå tom for å hoppe over)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Velg produsent (eller la stå tom for å hoppe over)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Produsentens delenummer" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Valgt firma er ikke en gyldig leverandør" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Valgt firma er ikke en gyldig produsent" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Produsentdel som matcher dette MPN-et, finnes allerede" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Leverandørdel som matcher denne SKU-en, finnes allerede" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategorinavn" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Produseres" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Lagervarer" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Total lagerbeholdning" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Dupliser del" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kopier innledende data fra en annen del" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Innledende lagerbeholdning" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Lag en del med innledende lagermengde" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Leverandøropplysninger" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Legg til innledende leverandørinformasjon for denne delen" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kopier kategoriparametre" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Kopier parametermaler fra valgt delkategori" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Eksisterende bilde" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Filnavn for et eksisterende del-bilde" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Bildefilen finnes ikke" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Godkjenn hele Stykklisten" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Kan Produsere" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minstepris" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Overstyr beregnet verdi for minimumspris" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Valuta for minstepris" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Makspris" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Overstyr beregnet verdi for maksimal pris" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Valuta for maksimal pris" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Oppdater" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Oppdater priser for denne delen" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Minsteprisen kan ikke være større enn maksimal pris" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Maksimal pris kan ikke være mindre enn minstepris" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Velg del å kopiere BOM fra" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Fjern eksisterende data" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Fjern eksisterende BOM-artikler før kopiering" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Inkluder arvede" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Inkluder BOM-artikler som er arvet fra maldeler" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Hopp over ugyldige rader" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Aktiver dette alternativet for å hoppe over ugyldige rader" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Kopier erstatningsdeler" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopier erstatningsdeler når BOM-elementer dupliseres" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Varsel om lav lagerbeholdning" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Antall å tildele" msgid "Label printing failed" msgstr "Utskrift av etikett mislyktes" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "Gir innebygd støtte for strekkoder" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF etikettskriver" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Gir innebygd støtte for å skrive ut PDF-etiketter" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Feilsøkingsmodus" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Aktiver feilsøkingsmodus - returnerer rå HTML i stedet for PDF" @@ -7500,7 +7673,7 @@ msgstr "Kantlinjer" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Liggende" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Installasjon av utvidelse vellykket" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Installerte utvidelsen til {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Utvidelse" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Ingen forfatter funnet" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Utvidelsen krever minst versjon {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Utvidelsen krever maks versjon {v}" @@ -7884,55 +8070,55 @@ msgstr "Installasjonen ble ikke bekreftet" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Full omlasting" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Utfør en full omlasting av utvidelsesregisteret" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Tvangsomlasting" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Tving en omlasting av utvidelsesregisteret, selv om det allerede er lastet" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Hent inn utvidelser" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Hent inn utvidelser og legg dem til i registeret" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Aktivér utvidelse" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Aktivér denne utvidelsen" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Malnavn" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Filnavnmønster" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtre" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Sidestørrelse for PDF-rapporter" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Generer rapport i landskapsorientering" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Bredde [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Etikettbredde, spesifisert i mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Høyde [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Etiketthøyde, spesifisert i mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Snutt" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Rapportsnuttfil" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Filbeskrivelse for snutt" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Ressurs" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Rapportressursfil" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Ressursfilbeskrivelse" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Installerte artikler" @@ -8248,184 +8438,196 @@ msgstr "Ingen resultat (obligatorisk)" msgid "No result" msgstr "Ingen resultat" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Asset-filen eksisterer ikke" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Bildefil ikke funnet" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image-taggen krever en Part-instans" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image-taggen krever en Company-instans" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Statuskode" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Ekstern plassering" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Del-tre" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Utløpsdato før" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Utløpsdato etter" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Foreldet" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Antall kreves" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Gyldig del må oppgis" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Oppgitt leverandørdel eksisterer ikke" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Serienumre kan ikke angis for en ikke-sporbar del" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Lagerplasseringstyper" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Lagerplassering" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Lagerplasseringer" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Eier" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Velg eier" @@ -8461,7 +8663,7 @@ msgstr "Velg eier" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Ekstern" @@ -8481,274 +8683,282 @@ msgstr "Lagerplasseringstype for denne plasseringen" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Lagervarer kan ikke plasseres i strukturelle plasseringer!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Lagervare kan ikke opprettes for virtuelle deler" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Elementet kan ikke tilhøre seg selv" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "Elementet må ha en produksjonsrefereanse om is_building=True" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Produksjonsreferanse peker ikke til samme del-objekt" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Overordnet lagervare" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Basisdel" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Velg en tilsvarende leverandørdel for denne lagervaren" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Hvor er denne lagervaren plassert?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Inpakningen denne lagervaren er lagret i" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Installert i" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Er denne artikkelen montert i en annen artikkel?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Serienummer for denne artikkelen" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Batchkode for denne lagervaren" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Lagerantall" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Kildeproduksjon" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Produksjon for denne lagervaren" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Brukt av" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Produksjonsordren som brukte denne lagervaren" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Kildeinnkjøpsordre" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Innkjøpsordre for denne lagervaren" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Tildelt Salgsordre" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Slett når oppbrukt" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Slett lagervaren når beholdningen er oppbrukt" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Innkjøpspris per enhet på kjøpstidspunktet" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Konvertert til del" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Delen er ikke angitt som sporbar" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Antall må være heltall" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Antallet stemmer ikke overens med serienumrene" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Lagervare har blitt tildelt en salgsordre" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Lagervare er montert i en annen artikkel" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Lagervare inneholder andre artikler" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Lagervare har blitt tildelt til en kunde" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Lagervare er for tiden i produksjon" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Serialisert lagerbeholdning kan ikke slås sammen" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Duplisert lagervare" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Lagervarer må referere til samme del" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Lagervarer må referere til samme leverandørdel" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Lagerstatuskoder må være like" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Oppføringsnotater" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Verdi må angis for denne testen" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Vedlegg må lastes opp for denne testen" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Testresultat" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Testens verdi" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Vedlegg til testresultat" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Testnotater" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Overodnet element" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Angi serienummer for nye artikler" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Leverandørens delnummer" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Utløpt" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Underordnede artikler" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Innkjøpspris for denne lagervaren, per enhet eller forpakning" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Angi antall lagervarer som skal serialiseres" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Antall kan ikke overstige tilgjengelig lagerbeholdning ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Til Lagerplassering" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Serienummer kan ikke tilordnes denne delen" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Seriernummer eksisterer allerede" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Velg lagervare å montere" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Antall å installere" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Angi antallet elementer som skal installeres" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Legg til transaksjonsnotat (valgfritt)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Antall å installere må være minst 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Lagervaren er utilgjengelig" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Valgt del er ikke i stykklisten" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Antall å installere må ikke overskride tilgjengelig antall" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Lagerplassering for den avinstallerte artikkelen" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Velg del å konvertere lagervare til" -#: stock/serializers.py:944 +#: 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:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "Kan ikke konvertere lagerprodukt med tildelt leverandørdel" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Lagervare statuskode" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Velg lagervarer for å endre status" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Ingen lagervarer valgt" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Underplasseringer" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Delen må være salgbar" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Artikkelen er tildelt en salgsordre" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Artikkelen er tildelt en produksjonsordre" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Kunde å tilordne lagervarer" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Valgt firma er ikke en kunde" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Lagervare-tildelignsnotater" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "En liste av lagervarer må oppgis" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notater om lagersammenslåing" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Tillat forskjellige leverandører" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Tillat lagervarer med forskjellige leverandørdeler å slås sammen" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Tillat forskjellig status" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Tillat lagervarer med forskjellige statuskoder å slås sammen" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Minst to lagervarer må oppgis" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Lagervare primærnøkkel verdi" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Lager transaksjonsnotater" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Sist gang tokenet ble brukt" msgid "Revoked" msgstr "Tilbakekalt" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Tillatelse satt" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Visning" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Tillatelse til å se elementer" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Legg til" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Tillatelse til å legge til elementer" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Endre" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Tillatelse til å endre elementer" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Slett" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Tillatelse til å slette elementer" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administrator" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Innkjøpsordrer" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Salgsordre" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Returordrer" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Brukernavn" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Fornavn" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Fornavn på brukeren" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Etternavn" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Etternavn på brukeren" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "E-postadressen til brukeren" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personale" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Har denne brukeren personelltillatelser" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superbruker" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Er denne brukeren en superbruker" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Er denne brukerkontoen aktiv" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Din konto er opprettet." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Vennligst bruk funksjonen for å tilbakestille passord for å logge inn" -#: users/serializers.py:452 +#: users/serializers.py:497 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 be4f340d19..502ba10bcd 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Nie znaleziono punktu końcowego API" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Dla operacji masowych należy podać wykaz przedmiotów lub filtrów" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Elementy muszą być podane jako lista" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Podano nieprawidłową listę artykułów" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filtry muszą być dostarczone jako kartka" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Podano niepoprawne filtry" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Wszystkie filtry muszą być używane tylko z true" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Żaden element nie spełnia podanych kryteriów" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nie dostarczono danych" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Użytkownik nie ma uprawnień do przeglądania tego modelu" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Podano nieprawidłową ilość" @@ -112,13 +105,13 @@ msgstr "Wprowadź dane" msgid "Invalid decimal value" msgstr "Niepoprawna wartość dziesiętna" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Uwagi" @@ -131,75 +124,91 @@ msgstr "Wartość '{name}' nie pojawia się w formacie wzoru" msgid "Provided value does not match required pattern: " msgstr "Podana wartość nie pasuje do wymaganego wzoru: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Nie można serializować więcej niż 1000 przedmiotów naraz" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Pusty ciąg numeru seryjnego" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Podwójny numer seryjny" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Nieprawidłowa grupa: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Zakres grupy {group} przekracza dozwoloną ilość ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nie znaleziono numerów seryjnych" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Usuń znaczniki HTML z tej wartości" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Dane zawierają zabronione treści znacznika" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Błąd połączenia" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serwer odpowiedział z nieprawidłowym kodem statusu" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Wystąpił wyjątek" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serwer odpowiedział z nieprawidłową wartością Content-Length" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Rozmiar obrazu jest zbyt duży" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Przekroczono maksymalny rozmiar pobieranego obrazu" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Zdalny serwer zwrócił pustą odpowiedź" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Podany adres URL nie jest poprawnym plikiem obrazu" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Adres E-Mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Musisz włączyć uwierzytelnianie dwuskładnikowe przed wykonaniem czegokolwiek innego." @@ -255,133 +264,108 @@ msgstr "Odniesienie musi być zgodne z wymaganym wzorem" msgid "Reference number is too large" msgstr "Numer odniesienia jest zbyt duży" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Błędny wybór" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nazwa" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Opis (opcjonalny)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Ścieżka" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikaty nazw nie mogą istnieć pod tym samym rodzicem" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notatki Markdown (opcjonalne)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Dane kodu kreskowego" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Dane kodu kreskowego stron trzecich" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hasz kodu kreskowego" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unikalny hasz danych kodu kreskowego" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Znaleziono istniejący kod kreskowy" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Niepowodzenie zadania" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Zadanie pracownika w tle '{f}' nie powiodło się po próbach {n}" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Błąd serwera" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Błąd został zapisany w logach serwera." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Numer musi być prawidłowy" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Waluta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Wybierz walutę z dostępnych opcji" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Nieprawidłowa wartość" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Obrazek zewnętrzny" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Adres URL zdalnego pliku obrazu" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Pobieranie obrazów ze zdalnego URL nie jest włączone" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Nie udało się pobrać obrazu ze zdalnego adresu URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "chiński (uproszczony)" msgid "Chinese (Traditional)" msgstr "chiński (tradycyjny)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Dostępna aktualizacja" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Dostępna jest aktualizacja dla InvenTree" @@ -553,30 +537,30 @@ msgstr "Niewłaściwa jednostka fizyczna" msgid "Not a valid currency code" msgstr "Nieprawidłowy kod waluty" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Status zamówienia" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Budowa nadrzędna" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Obejmuje warianty" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Obejmuje warianty" msgid "Part" msgstr "Komponent" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategoria" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Budowa poprzednika" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Przypisane do mnie" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Stworzony przed" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Stworzony po" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Ma datę rozpoczęcia" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Data rozpoczęcia przed" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Data rozpoczęcia po" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Posiada docelową datę" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Data docelowa przed" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Docelowa data po" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Zakończone przed" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Zakończone po" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Minimalna data" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Maksymalna data" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Wyklucz drzewo" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Materiał eksploatacyjny" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcjonalne" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Złożenie" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Śledzony" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testowalne" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Zaległe zamówienie" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Przydzielono" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "W Zamówieniu" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Zlecenie Budowy" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lokalizacja" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Wyjście" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Zlecenia budowy" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Zbiór BOM nie został zatwierdzony" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Odpowiedzialny użytkownik lub grupa muszą być określone" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Nie można zmienić elementu kompletacji" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Data docelowa musi być po dacie rozpoczęcia" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Odwołanie do zamówienia wykonania" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Odwołanie do zamówienia wykonania" msgid "Reference" msgstr "Referencja" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Krótki opis produkcji (opcjonalny)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Wybierz część do budowy" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Odwołanie do zamówienia sprzedaży" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Lokalizacja źródła" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Budowa zewnętrzna" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Lokalizacja docelowa" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Ilość do stworzenia" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Ilość przedmiotów do zbudowania" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Ukończone elementy" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Ilość produktów magazynowych które zostały ukończone" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Status budowania" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Kod statusu budowania" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Kod partii" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Kod partii dla wyjścia budowy" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Data utworzenia" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Data rozpoczęcia budowy" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Zaplanowana data rozpoczęcia dla tego zamówienia budowy" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Docelowy termin zakończenia" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Data zakończenia" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "zrealizowane przez" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Wydany przez" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Użytkownik, który wydał to zamówienie" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odpowiedzialny" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Użytkownik lub grupa odpowiedzialna za te zlecenie produkcji" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Link Zewnętrzny" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link do zewnętrznego adresu URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Priorytet budowy" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Priorytet tego zamówienia produkcji" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Kod projektu" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Kod projektu dla tego zlecenia produkcji" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Kolejność kompilacji została zakończona" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Należy podać numery seryjne dla lokalizowania części" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nie określono danych wyjściowych budowy" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Budowanie wyjścia jest już ukończone" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Skompilowane dane wyjściowe nie pasują do kolejności kompilacji" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Ilość musi być większa niż zero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Ilość nie może być większa niż ilość wyjściowa" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Zbuduj obiekt" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Ilość" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Wymagana ilość dla zlecenia produkcji" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Wybrana pozycja magazynowa nie pasuje do pozycji w zestawieniu BOM" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Ilość musi wynosić 1 dla serializowanych zasobów" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Pozycja magazynowa jest nadmiernie przydzielona" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Element magazynowy" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Lokalizacja magazynowania przedmiotu" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Ilość zapasów do przydzielenia do produkcji" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Zainstaluj do" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Docelowa lokalizacja magazynowa przedmiotu" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Poziom budowania" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nazwa komponentu" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Numer seryjny" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automatycznie przydzielaj numery seryjne" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatycznie przydzielaj wymagane elementy z pasującymi numerami seryjnymi" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Poniższe numery seryjne już istnieją lub są nieprawidłowe" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Odrzuć przydziały" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Zaakceptuj niekompletną alokację" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Usuń produkcje, które nie zostały zakończone" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Niedozwolone" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Zaakceptuj jako zużyte przez zlecenie produkcji" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Nadmierny przydział zasobów" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Zaakceptuj nieprzydzielone" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Wymagany stan nie został w pełni przypisany" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Akceptuj niekompletne" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Towar musi znajdować się w magazynie" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Wyklucz lokalizację" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Wyklucz produkty magazynowe z wybranej lokalizacji" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Magazyn wymienny" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Towary magazynowe w wielu lokalizacjach mogą być stosowane zamiennie" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Zastępczy magazyn" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Przedmiot opcjonalny" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Przydziel opcjonalne elementy BOM do zbudowania zamówienia" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Odniesienie BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID części BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nazwa części BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Wersja" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Część dostawcy" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Ilość zarezerwowana" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Możliwość śledzenia" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Zezwalaj na warianty" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Element BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "W produkcji" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Zew. zasoby magazynowe" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Dostępna ilość" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Dostępny magazyn zastępczy" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "Wstrzymane" msgid "Cancelled" msgstr "Anulowano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Zakończono" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Jest plikiem" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "Brak wtyczki" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Zaktualizowany" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Data ostatniej aktualizacji" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Zaktualizowano przez" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Użytkownik, który ostatnio zaktualizował ten obiekt" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unikalny kod projektu" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Opis projektu" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Klucz ustawień" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Ustawienia wartości" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Wybrana wartość nie jest poprawną opcją" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Wartość musi być wartością binarną" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Wartość musi być liczbą całkowitą" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Wartość musi być poprawną liczbą" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Wartość nie zgadza się z kontrolą poprawności" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Ciąg musi być unikatowy" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Użytkownik" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Cena" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Cena jednostkowa po określonej ilości" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Punkt końcowy" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktywny" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token dostępu" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Sekret" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Współdzielony sekret dla HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Id wiadomości" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Unikalny identyfikator dla tej wiadomości" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Host, od którego otrzymano tę wiadomość" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Nagłówek" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Nagłówek tej wiadomości" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Zawartość" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Treść tej wiadomości" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Opracowany na" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Czy prace nad tą wiadomością zostały zakończone?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Tytuł" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Łącze" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Opublikowano" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Podsumowanie" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Czytaj" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Czy ta wiadomość była przeczytana?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Plik obrazu" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Jednostka Niestandardowa" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Symbol jednostki musi być unikalny" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Nazwa jednostki musi być prawidłowym identyfikatorem" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nazwa jednostki" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Opcjonalny symbol jednostki" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definicja" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definicja jednostki" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Załącznik" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Brak pliku" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Brak zewnętrznego odnośnika" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Typ modelu" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Docelowy typ modelu dla obrazu" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Wybierz plik do załączenia" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentarz" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Komentarz do załącznika" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Data dodania" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Data przesłania pliku" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Rozmiar pliku" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Rozmiar pliku w bajtach" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Wartość" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etykieta" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Kolor" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Model musi być wybrany" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Klucz musi być wybrany" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Zablokowany" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Utworzony" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Ostatnia aktualizacja" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Jednostki" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Aktywne" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Szablon" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Dane" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Wartość parametru" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Uwaga" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Wynik" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Doręczono" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Klucz" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "Nadpisz" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Jest uruchomiony" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Oczekujce zadania" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Zaplanowane zadania" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Zadania zakończone błędem" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID zadania" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Unikalny identyfikator zadania" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Blokada" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Czas blokady" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nazwa zadania" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funkcja" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nazwa funkcji" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumenty" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumenty zadania" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nazwa pliku" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Typ modelu" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista wyboru jest zablokowana" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Brak grupy" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Adres URL witryny jest zablokowany przez konfigurację" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Wymagane ponowne uruchomienie" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Zmieniono ustawienie, które wymaga restartu serwera" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Oczekujące migracje" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Liczba oczekujących migracji bazy danych" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Aktywne kody ostrzeżeń" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID instancji" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Unikalny identyfikator dla tej instancji InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nazwa instancji serwera" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Użyj nazwy instancji" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nazwa firmy" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Wewnętrzna nazwa firmy" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Bazowy URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Bazowy adres URL dla instancji serwera" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Domyślna waluta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Interwał aktualizacji waluty" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dni" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Wtyczka aktualizacji waluty" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Pobierz z adresu URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Zezwól na pobieranie zewnętrznych obrazów i plików z zewnętrznego URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limit rozmiaru pobierania" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Ścisła weryfikacja adresu URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Wymagaj specyfikacji schematu podczas sprawdzania poprawności adresów URL" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Częstotliwość sprawdzania aktualizacji" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Jak często aktualizować kursy wymiany walut (ustaw zero aby wyłączyć)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatyczna kopia zapasowa" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Włącz automatyczną kopię zapasową bazy danych i plików multimedialnych" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Interwał automatycznego tworzenia kopii zapasowych" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Określ liczbę dni między zdarzeniami automatycznej kopii zapasowej" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Interwał usuwania zadań" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Obsługa kodu kreskowego" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Wyrażenie regularne IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Zezwól na powtarzający się IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Zezwól na edycję IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Skopiuj BOM komponentu" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Możliwość zakupu" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Części są domyślnie z możliwością zakupu" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Możliwość sprzedaży" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Części są domyślnie z możliwością sprzedaży" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Części są domyślnie z możliwością śledzenia" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Wirtualny" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Części są domyślnie wirtualne" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Pokaż powiązane części" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Użyj cennika dostawcy" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Nadpisanie historii zakupów" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Ceny wewnętrzne" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Włącz drukowanie etykiet" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Włącz drukowanie etykiet z interfejsu WWW" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI etykiety" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Włącz raporty" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Tryb Debugowania" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: 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:674 +#: 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:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Przekonwertuj walutę" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Automatycznie wypełniaj zlecenia zakupu" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Włącz opcję zapomnianego hasła" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Włącz rejestrację" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Włącz SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Włącz SSO na stronach logowania" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Włącz rejestrację SSO" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Włącz synchronizację grupy SSO" -#: common/setting/system.py:952 +#: 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Adres e-mail jest wymagany" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Autouzupełnianie użytkowników SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "E-mail dwa razy" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Hasło dwukrotnie" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupuj przy rejestracji" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Wymuś MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Użytkownicy muszą używać zabezpieczeń wieloskładnikowych." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Sprawdź wtyczki przy starcie" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Sprawdź dostępność aktualizacji wtyczek" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Włącz okresowe sprawdzanie aktualizacji zainstalowanych wtyczek" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Włącz integrację URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Włącz wtyczki, aby dodać ścieżki URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Włącz integrację z aplikacją" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Włącz wtyczki, aby dodać aplikacje" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Włącz wtyczki, aby uruchamiać zaplanowane zadania" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Włącz kody projektów" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Włącz kody projektów do śledzenia projektów" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Komponent jest aktywny" msgid "Manufacturer is Active" msgstr "Producent jest aktywny" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Producent" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Firma" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Firmy" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Opis firmy" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Opis firmy" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Strona WWW" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Witryna internetowa firmy" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Numer telefonu" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Numer telefonu kontaktowego" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Kontaktowy adres e-mail" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Punkt kontaktowy" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link do informacji o zewnętrznym przedsiębiorstwie" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Czy sprzedajesz produkty tej firmie?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Czy kupujesz przedmioty od tej firmy?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Czy to przedsiębiorstwo produkuje części?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adres" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Miasto/Region" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Kod pocztowy miasto/region" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Stan/Województwo" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Stan lub województwo" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Kraj" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Kraj" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notatki przewozowe kuriera" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notatki dla kuriera" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Wewnętrzne notatki przewozowe" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notatki wysyłkowe do użytku wewnętrznego" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Komponent producenta" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Część bazowa" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Wybierz część" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Wybierz producenta" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Numer producenta komponentu" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dostawca" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Wybierz dostawcę" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "koszt podstawowy" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Opakowanie" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Opakowanie części" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Ilość w opakowaniu" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "wielokrotność" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Zamów wiele" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Dostępność zaktualizowana" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Domyślna waluta używana dla tego dostawcy" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Na stanie" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Ważny" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Liczba kopii do wydrukowania dla każdej etykiety" msgid "Connected" msgstr "Połączono" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Nieznany" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupa" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Numer zamówienia" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Utworzony przez" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Posiada ceny" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Zamówienie" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Komponent wewnętrzny" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Zamówienie oczekujące" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Zakończone" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Zlecenie zakupu" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Zlecenie zakupu" msgid "Sales Order" msgstr "Zamówienie zakupu" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Cena całkowita" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link do zewnętrznej witryny" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data docelowa" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Data wydania" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Data wystawienia zamówienia" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Użytkownik lub grupa odpowiedzialna za to zamówienie" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Odniesienie zamówienia" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Status zamówienia zakupu" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "odebrane przez" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Przeznaczenie" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Pozycja nie pasuje do zlecenia zakupu" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Wartość musi być liczbą dodatnią" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klient" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Data wysyłki" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "wysłane przez" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Ilość elementów" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "Odebrane" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Cena zakupu" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Cena zakupu jednostkowego" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Cena sprzedaży" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Jednostkowa cena sprzedaży" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Wysłane" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Wysłana ilość" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Data wysyłki" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Sprawdzone przez" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Użytkownik, który sprawdził tę wysyłkę" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Przesyłka" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Numer przesyłki" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Numer śledzenia" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informacje o śledzeniu przesyłki" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Przesyłka została już wysłana" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Zarezerwowana ilość nie może przekraczać ilości na stanie" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Alokowana ilość musi być większa niż zero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Linia" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Komponent" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Zamówienie nie może zostać anulowane" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Zlecenie zakupu musi być określone" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Dostawca musi być zgodny ze zleceniem zakupu" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Zlecenie zakupu musi być zgodne z dostawcą" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Data ważności" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Kod kreskowy" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "Zwrot pieniędzy" msgid "Reject" msgstr "Odrzuć" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Zaległe zlecenie zakupu" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Zlecenie zakupu {po} jest teraz zaległe" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Kategoria komponentu" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Kategorie części" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Domyślna lokalizacja" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "Wartość domyślna" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Części" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nazwa komponentu" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Czy szablon" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Czy ta część stanowi szablon części?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Czy ta część jest wariantem innej części?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Wariant" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Słowa kluczowe" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Wersja" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Domyślne wygasanie" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimalny stan magazynowy" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Czy ten komponent może być zbudowany z innych komponentów?" -#: part/models.py:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Czy ta część wymaga śledzenia każdego towaru z osobna?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Czy ta część jest aktywna?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Tworzenie użytkownika" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Sprzedaj wiele" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Data" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nazwa testu" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Testowy opis" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Wprowadź opis do tego testu" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Wymagane" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Wymaga wartości" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Wymaga załącznika" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Wybierz część nadrzędną" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Podczęść" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Ten element BOM jest opcjonalny" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notatki pozycji BOM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Suma kontrolna" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Zatwierdzone" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Część zastępcza" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Część 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Część 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Wybierz powiązaną część" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Podkategorie" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Waluta zakupu tego towaru" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopiuj obraz" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Kopiuj BOM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Kopiuj parametry" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Towary" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Duplikuj część" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Usuń istniejące dane" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Pomiń nieprawidłowe wiersze" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Włącz tę opcję, aby pominąć nieprawidłowe wiersze" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Tryb Debugowania" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Wtyczka" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nie znaleziono autora" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "Instalacja nie została potwierdzona" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Pełne przeładowanie" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Wykonaj pełne przeładowanie rejestru wtyczek" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Wymuś przeładowanie" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Wymuś przeładowanie rejestru wtyczek, nawet jeśli jest już załadowany" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Zbierz wtyczki" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Zbierz wtyczki i dodaj je do rejestru" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Aktywuj wtyczkę" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Aktywuj tę wtyczkę" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nazwa szablonu" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Wzór nazwy pliku" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtry" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Domyślna wielkość strony dla raportów PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Renderuj raport w orientacji poziomej" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Szerokość [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Wysokość [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Wycinek" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numer Seryjny" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Zainstalowane elementy" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Lokacje stanu magazynowego" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Właściciel" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Wybierz właściciela" @@ -8461,7 +8663,7 @@ msgstr "Wybierz właściciela" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Nadrzędny towar" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Część podstawowa" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Wybierz pasującą część dostawcy dla tego towaru" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Zainstalowane w" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Ilość w magazynie" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Wyszukaj zlecenie zakupu" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Zlecenie zakupu dla tego towaru" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Usuń po wyczerpaniu" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Ilość musi być liczbą całkowitą" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Notatki do wpisu" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Należy podać wartość dla tego testu" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Wynik testu" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Element nadrzędny" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Termin minął" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Elementy podrzędne" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Numer seryjny już istnieje" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Podlokalizacje" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Część musi być dostępna do sprzedaży" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Uprawnienia nadane" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Widok" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Uprawnienie do wyświetlania przedmiotów" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Dodaj" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Uprawnienie do dodawania przedmiotów" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Zmień" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Uprawnienie do edycji przedmiotów" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Usuń" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Uprawnienie do usuwania przedmiotów" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "Zlecenia zakupu" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "Zlecenia zakupu" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Czy to konto użytkownika jest aktywne" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Twoje konto zostało utworzone." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Zresetuj hasło" -#: users/serializers.py:452 +#: users/serializers.py:497 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 c8d7485abe..34935b3cd2 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint não encontrado" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Usuário não tem permissão para ver este modelo" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Quantidade fornecida inválida" @@ -112,13 +105,13 @@ msgstr "Insira uma Data" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Anotações" @@ -131,75 +124,91 @@ msgstr "Valor '{name}' não está no formato correto" msgid "Provided value does not match required pattern: " msgstr "O valor fornecido não corresponde ao padrão exigido: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Número serial em branco" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Número de série duplicado" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nenhum número de série foi encontrado" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Remova as \"tags\" HTML deste valor" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Erro de conexão" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "O servidor respondeu com código estado inválido" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Ocorreu uma exceção" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Tamanho da imagem muito grande" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "O download da imagem excedeu o tamanho máximo" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "O servidor remoto retornou resposta vazia" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "A URL fornecida não é um arquivo de imagem válido" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "A referência deve corresponder ao padrão exigido" msgid "Reference number is too large" msgstr "O número de referência é muito grande" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Escolha inválida" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descrição" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descrição (opcional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Caminho" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomes duplicados não podem existir sob o mesmo parental" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notas Markdown (opcional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Dados de código de barras" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Dados de código de barras de terceiros" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash de código de barras" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash exclusivo de dados de código de barras" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Erro de servidor" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Log de erro salvo pelo servidor." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Preicsa ser um numero valido" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Moeda" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Selecione a Moeda nas opções disponíveis" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Imagens Remota" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL do arquivo de imagem remoto" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Baixar imagens de URL remota não está habilitado" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Chinês (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chinês (Tradicional)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Unidade física inválida" msgid "Not a valid currency code" msgstr "Não é um código de moeda válido" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Situação do pedido" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Produção Progenitor" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Peça" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categoria" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Produção deve ser cancelada antes de ser deletada" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumível" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montagem" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Monitorado" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Alocado" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "No pedido" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 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:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Local" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Ordens de Produções" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Usuário ou grupo responsável deve ser especificado" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Peça da ordem de produção não pode ser alterada" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referência do pedido de produção" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referência do pedido de produção" msgid "Reference" msgstr "Referência" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Breve descrição da produção (opcional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Selecionar peça para produção" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referência do pedido de venda" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Local de Origem" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Local de Destino" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Quantidade de Produção" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Número de itens em estoque para produzir" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Itens concluídos" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Número de itens em estoque concluídos" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Progresso da produção" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Código de situação da produção" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Código de Lote" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Código do lote para esta saída de produção" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Criado em" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Data alvo final" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Data de conclusão" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "Concluído por" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Usuário que emitiu este pedido de produção" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsável" -#: build/models.py:409 +#: build/models.py:420 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:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Link Externo" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link para URL externa" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Prioridade de Produção" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioridade deste pedido de produção" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Código do projeto" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Código do projeto para este pedido de produção" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Um pedido de produção foi concluído" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nenhuma saída de produção especificada" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Saída de produção já completada" -#: build/models.py:1019 +#: build/models.py:1030 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:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Quantidade deve ser maior que zero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Item da linha de Produção" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Objeto de produção" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantidade" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Quantidade necessária para o pedido de produção" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Item estoque selecionado não coincide com linha da LDM" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Quantidade deve ser 1 para estoque serializado" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "O item do estoque está sobre-alocado" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Item de estoque" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Origem do item em estoque" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Quantidade do estoque para alocar à produção" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Instalar em" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Destino do Item do Estoque" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nome da Peça" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Saída da Produção" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Esta saída de produção já foi concluída" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "A saída de produção não está completamente alocada" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Entre a quantidade da saída de produção" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Quantidade inteira necessária para peças rastreáveis" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Números de Série" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Digite os números de série para saídas de produção" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Local de estoque para a produção" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Alocar Números de Série Automaticamente" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Uma lista de saídas de produção deve ser fornecida" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Local de estoque para saídas recicladas" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Descartar alocações" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar quaisquer alocações de estoque para saídas sucateadas" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Motivo para sucatear saída(s) de produção" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Local para saídas de produção concluídas" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Aceitar Alocação Incompleta" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consumir Estoque Alocado" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Remover Saídas Incompletas" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Não permitido" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Aceitar conforme consumido por esta ordem de produção" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Desatribua antes de completar este pedido de produção" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Estoque sobrealocado" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Alguns itens de estoque foram sobrealocados" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Aceitar não alocados" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Estoque obrigatório não foi totalmente alocado" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Aceitar Incompleto" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Quantidade de produção requerida não foi concluída" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Pedido de produção tem saídas incompletas" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linha de produção" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Saída da Produção" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Saída de produção deve indicar a mesma produção" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Item da linha de produção" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Item deve estar em estoque" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Alocação do Item precisa ser fornecida" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Local não incluso" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Não incluir itens de estoque deste local" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Estoque permutável" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Substituir Estoque" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Permitir alocação de peças substitutas" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Itens opcionais" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Alocar itens LDM opcionais para o pedido de produção" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Falha ao iniciar tarefa de auto-alocação" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Fornecedor da Peça" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Quantidade Alocada" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Rastreável" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Permitir variações" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Item LDM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Em Produção" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Estoque Disponível" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Completado" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Estoque obrigatório para o pedido de produção" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Pedido de produção vencido" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Pedido de produção {bo} está atrasada" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "É uma Ligação" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "É um arquivo" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "O Utilizador não tem permissão para remover este anexo" @@ -1551,798 +1539,822 @@ msgstr "Nenhum código de moeda válido foi fornecido" msgid "No plugin" msgstr "Sem extensão" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Atualizado" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Tempo da última atualização" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Código único do projeto" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Descrição do projeto" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valor da Configuração" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Valor deve ser um valor booleano" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Valor deve ser um número inteiro" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "A frase senha deve ser diferenciada" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Usuario" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Quantidade de Parcelamentos" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Preço" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Preço unitário na quantidade especificada" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Ponto final" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nome para este webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Ativo" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Este gancho web está ativo" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token de acesso" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Segredo" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Segredo compartilhado para HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID da Mensagem" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identificador exclusivo desta mensagem" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Servidor" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Servidor do qual esta mensagem foi recebida" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Cabeçalho" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Cabeçalho da mensagem" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Corpo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Corpo da mensagem" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Ponto do qual esta mensagem foi recebida" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Trabalhado em" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "O trabalho desta mensagem foi concluído?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Título" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Ligação" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publicado" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Resumo" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Lida" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Esta notícia do item foi lida?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Arquivo de imagem" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Nome da unidade deve ser um identificador válido" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nome da unidade" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Símbolo de unidade opcional" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definição" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definição de unidade" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Anexo" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Arquivo ausente" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Link externo não encontrado" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Selecione arquivo para anexar" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Comentario" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valor" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Criado" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Última atualização" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Modelo de parâmetro" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Parâmetros da caixa de seleção não podem ter unidades" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Os parâmetros da caixa de seleção não podem ter escolhas" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Escolhas devem ser únicas" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Nome do modelo de parâmetro deve ser único" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nome do Parâmetro" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unidades" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Unidades físicas para este parâmetro" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Descrição do Parâmetro" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Caixa de seleção" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Este parâmetro é uma caixa de seleção?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Escolhas" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opções válidas para este parâmetro (separadas por vírgulas)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Escolha inválida para valor do parâmetro" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Modelo" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Dados" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Valor do Parâmetro" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Anotação" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Campo opcional de notas" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultado" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Chave" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Itens Recebidos" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Executando" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Tarefas Pendentes" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tarefas Agendadas" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tarefas com Falhas" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID da Tarefa" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ID Único da Tarefa" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Tempo de bloqueio" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nome da tarefa" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Função" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nome da função" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumentos da tarefa" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argumentos de Palavra-chave" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argumentos Palavra-chave da Tarefa" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nome do arquivo" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Nenhum grupo" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "URL do site está bloqueada por configuração" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Reinicialização necessária" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Uma configuração que requer uma reinicialização do servidor foi alterada" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migrações pendentes" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Número de migrações pendentes na base de dados" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nome da Instância do Servidor" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Descritor de frases para a instância do servidor" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Usar nome da instância" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Usar o nome da instância na barra de título" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Restringir a exibição 'sobre'" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Mostrar 'sobre' modal apenas para superusuários" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nome da empresa" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nome interno da Empresa" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL de Base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL Base da instância do servidor" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Moeda Padrão" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Selecione a moeda base para cálculos de preços" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Moedas suportadas" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Lista de códigos de moeda suportados" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervalo de Atualização da Moeda" -#: common/setting/system.py:265 +#: 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dias" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Extensão de Atualização de Moeda" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Extensão de Atualização de Moeda a utilizar" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Baixar do URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Permitir baixar imagens remotas e arquivos de URLs externos" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limite de tamanho para baixar" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maior tamanho de imagem remota baixada permitida" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Usuário-agente utilizado para baixar da URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Permitir a substituição de imagens e arquivos usados baixados por usuário-agente (deixar em branco por padrão)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validação rigorosa de URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Exigir especificação de esquema ao validar URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Atualizar Intervalo de Verificação" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Frequência para verificar atualizações (defina como zero para desativar)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Cópia de Segurança Automática" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Ativar cópia de segurança automática do banco de dados e arquivos de mídia" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervalo de Backup Automático" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Especificar o número de dia entre as cópias de segurança" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervalo para Excluir da Tarefa" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Os resultados da tarefa no plano de fundo serão excluídos após um número especificado de dias" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervalo para Excluir do Registro de Erro" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Registros de erros serão excluídos após um número especificado de dias" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervalo para Excluir de Notificação" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Notificações de usuários será excluído após um número especificado de dias" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Suporte aos códigos de barras" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Ativar suporte a leitor de código de barras na interface web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Atraso na entrada de código de barras" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tempo de atraso de processamento de entrada de barras" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Suporte a código de barras via Câmera" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Permitir escanear código de barras por câmera pelo navegador" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revisões de peças" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Habilitar campo de revisão para a Peça" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Permitir a exclusão da Montagem" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Padrão de expressão regular adequado para Peça IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Permitir Duplicação IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que várias peças compartilhem o mesmo IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Permitir Edição IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copiar dados da LDM da Peça" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copiar Dados de Parâmetro da Peça" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copiar Dados Teste da Peça" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copiar Parâmetros dos Modelos de Categoria" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Peças são modelos por padrão" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Componente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Comprável" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Peças são compráveis por padrão" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Vendível" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Peças vão vendíveis por padrão" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Peças vão rastreáveis por padrão" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Peças são virtuais por padrão" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Mostra peças relacionadas" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Mostrar peças relacionadas para uma peça" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Dados Iniciais de Estoque" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Dados Iniciais de Fornecedor" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formato de Exibição do Nome da Peça" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formato para exibir o nome da peça" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Ícone de Categoria de Peça Padrão" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de Casas Decimais do Preço" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Máximo Casas Decimais de Preço" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Usar Preços do Fornecedor" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Sobrescrever histórico de compra" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Usar Preços do Item em Estoque" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Idade do preço do Item em Estoque" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Usar Preço Variável" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir preços variáveis nos cálculos de valores gerais" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Apenas Ativar Variáveis" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervalo de Reconstrução de Preços" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Preços Internos" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Habilitar preços internos para peças" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Sobrepor Valor Interno" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Ativar impressão de etiquetas" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Ativar impressão de etiqueta pela interface da internet" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI da Imagem na Etiqueta" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Habilitar Relatórios" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Ativar geração de relatórios" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Modo de depuração" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Gerar relatórios em modo de depuração (saída HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Relatório de erros" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registro de erros que ocorrem ao gerar relatórios" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Tamanho da página" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Tamanho padrão da página PDF para relatórios" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forçar Unidades de Parâmetro" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Seriais Únicos Globais" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Excluir Estoque Esgotado" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Modelo de Código de Lote" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Validade do Estoque" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Ativar função de validade de estoque" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vender estoque expirado" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Permitir venda de estoque expirado" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Tempo de Estoque Inativo" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Produzir Estoque Vencido" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Permitir produção com estoque vencido" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Controle de propriedade do estoque" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Ativar controle de propriedade sobre locais e itens de estoque" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Ícone padrão do local de estoque" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Mostrar Itens de Estoque Instalados" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Exibir itens de estoque instalados nas tabelas de estoque" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Verificar BOM ao instalar itens" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Permitir Transferência Fora do Estoque" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Produção" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Requer Proprietário Responsável" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Um proprietário responsável deve ser atribuído a cada ordem" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Bloquear até os Testes serem Aprovados" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Ativar Pedidos de Devolução" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Devolução" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Editar os Pedidos de Devolução Concluídos" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Venda" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Envio Padrão de Pedidos de Venda" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Editar os Pedidos de Vendas concluídos" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "Modelo de Referência de Pedidos de Compras" - -#: common/setting/system.py:889 -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:901 -msgid "Edit Completed Purchase Orders" -msgstr "Editar Pedidos de Compra Concluídos" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Modelo de Referência de Pedidos de Compras" + +#: common/setting/system.py:918 +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 +msgid "Edit Completed Purchase Orders" +msgstr "Editar Pedidos de Compra Concluídos" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Pedidos de Compra" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Habitar esquecer senha" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Habilitar cadastro" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Ativar SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Ativar SSO na página de acesso" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Ativar registro SSO" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email obrigatório" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Exigir do usuário o e-mail no cadastro" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Auto-preencher usuários SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Enviar email duplo" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "No registro pedir aos usuários duas vezes pelo email" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Senha duas vezes" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "No registro pedir aos usuários duas vezes pela senha" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Domínios permitidos" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupo no cadastro" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Forçar AMF" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Os usuários devem usar uma segurança multifator." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Checar extensões no início" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Verificar por atualizações de plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Ativar integração URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Ativar extensão para adicionar rotas URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Ativar integração de navegação" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Ativar extensões para integrar à navegação" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Ativa integração com aplicativo" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Ativar extensões para adicionar aplicativos" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Ativar integração do calendário" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Ativar extensões para executar tarefas agendadas" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Ativar integração de eventos" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Ativar extensões para responder a eventos internos" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Excluir Locais Externos" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Período de Balanço Automático" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Mostrar nomes completos dos usuários" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Mostrar Nomes Completos em vez de Nomes de Usuário" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Receber relatório de erros" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Receber notificações para erros do sistema" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Últimas máquinas de impressão utilizadas" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Empresa" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Empresas" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Descrição da empresa" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Descrição da empresa" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Página Web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL do Site da empresa" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Número de telefone" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Número de telefone do contato" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Endereço de e-mail do contato" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contato" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Ponto de contato" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link para informações externas da empresa" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Você vende itens para esta empresa?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Você compra itens desta empresa?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Esta empresa fabrica peças?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Moeda padrão utilizada para esta empresa" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Endereço" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Endereços" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Selecione a Empresa" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Título do endereço" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Título descrevendo a entrada de endereço" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Endereço Principal" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Definir como endereço principal" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Linha 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Linha de endereço 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Linha 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Linha de endereço 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Código Postal" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Cidade/Região" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Código Postal Cidade / Região" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Estado/Provincia" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Estado ou Província" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "País" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "País do endereço" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notas de envio da transportadora" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notas para o envio da transportadora" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Notas de envio interno" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notas de envio para uso interno" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link para as informações do endereço (externo)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Peça do Fabricante" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Peça base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Selecionar peça" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Selecionar fabricante" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "NPF" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Número de Peça do Fabricante" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Descrição da peça do fabricante" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Unidades de pacote deve ser maior do que zero" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornecedor" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Selecione o fornecedor" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unidade de reserva de estoque fornecedor" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Selecionar peça do fabricante" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Descrição da peça fornecedor" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "preço base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Taxa mínima (ex.: taxa de estoque)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Embalagem" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Embalagem de peças" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Quantidade de embalagens" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "múltiplo" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Pedir múltiplos" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Quantidade disponível do fornecedor" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilidade Atualizada" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Data da última atualização da disponibilidade dos dados" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Moeda padrão utilizada para este fornecedor" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Em Estoque" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Válido" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Desconhecido" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupo" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Referência do Pedido" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Criado por" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Pedido" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Peça Interna" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Concluído" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Pedido de Compra" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Pedido de Compra" msgid "Sales Order" msgstr "Pedido de Venda" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Preço Total" msgid "Total price for this order" msgstr "Preço total deste pedido" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Moeda do pedido" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Moeda para este pedido (deixe em branco para usar o padrão da empresa)" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "O contato não corresponde à empresa selecionada" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Descrição do pedido (opcional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Selecione o código do projeto para este pedido" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link para página externa" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data alvo" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Data de emissão" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Dia que o pedido foi feito" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Usuário ou grupo responsável para este pedido" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Ponto de contato para este pedido" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Endereço da empresa para este pedido" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Referência do pedido" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Situação" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Situação do pedido de compra" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Empresa da qual os itens estão sendo encomendados" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Referencia do fornecedor" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Código de referência do pedido fornecedor" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "recebido por" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Dia que o pedido foi concluído" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destino" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Fornecedor de peça deve corresponder a fornecedor da OC" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "O item de linha não corresponde ao pedido de compra" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Quantidade deve ser um número positivo" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Empresa para qual os itens foi vendidos" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Referência do Cliente " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Código de Referência do pedido do cliente" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Data de Envio" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Apenas um pedido aberto pode ser marcado como completo" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Quantidade do item" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Referência do Item em Linha" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Observações do Item de Linha" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Descrição item de linha (opcional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contexto adicional para esta linha" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Preço Unitário" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "A peça do fornecedor deve corresponder ao fornecedor" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Fornecedor da Peça" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Recebido" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Número de itens recebidos" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Preço de Compra" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Preço unitário de compra" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Preço de Venda" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Preço de venda unitário" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Quantidade enviada" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Data do envio" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Data de Entrega" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Data da entrega do envio" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Verificado por" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Usuário que verificou esta remessa" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Remessa" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Número do Envio" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Número de Rastreamento" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informação de rastreamento da remessa" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Número da Fatura" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Número de referência para fatura associada" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "O pedido já foi enviado" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Remessa não foi alocada nos itens de estoque" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "O item do estoque não foi atribuído" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "A quantidade de alocação não pode exceder a quantidade em estoque" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Quantidade alocada deve ser maior que zero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Quantidade deve ser 1 para item de estoque serializado" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Pedidos de venda não coincidem com a remessa" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Remessa não coincide com pedido de venda" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Linha" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Referência de remessa do pedido de venda" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Selecione o item de estoque para alocar" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Insira a quantidade de atribuição de estoque" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Referência de Pedidos de Devolução" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Empresa da qual os itens estão sendo retornados" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Estado do pedido de retorno" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Selecione o item a ser devolvido pelo cliente" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Data de Recebimento" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Despesa/gastos" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Gastos com esta linha de itens" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Itens de linha" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Nome do Fornecedor" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Pedido não pode ser cancelado" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "O pedido tem itens da linha incompletos" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "O pedido não está aberto" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Moeda de preço de compra" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Código (SKU)" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Numero interno do produto" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "A peça do fornecedor deve ser especificada" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "O pedido de compra deve ser especificado" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "O fornecedor deve corresponder o pedido de compra" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Pedido de compra deve corresponder ao fornecedor" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Itens de linha" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Selecione o local de destino para os itens recebidos" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Digite o código do lote para itens de estoque recebidos" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Data de validade" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Digite o número de série para itens de estoque recebidos" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Código de barras lido" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Código de barras já em uso" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Itens de linha deve ser providenciados" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Loca de destino deve ser especificado" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Código de barras fornecido deve ser único" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Envios concluídos" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Moeda de preço de venda" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nenhum detalhe da remessa fornecido" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Quantidade deve ser positiva" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Digite números de série para alocar" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "O pedido já foi enviado" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "O envio não está associado a este pedido" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Devolver item do pedido" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Item do pedido não bate com o pedido de devolução" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Item do pedido já foi recebido" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Tipo de moeda para o item do pedido" @@ -5598,146 +5742,150 @@ msgstr "Reembolsar" msgid "Reject" msgstr "Recusar" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Pedido de compra vencido" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Pedido de compra {po} está atrasada" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Pedido de venda vencido" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Pedido de venda {so} está atrasada" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Categoria da Peça" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Categorias de Peça" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Local Padrão" @@ -5778,7 +5926,7 @@ msgstr "Palavras-chave padrão para peças nesta categoria" msgid "Icon" msgstr "Ícone" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ícone (opcional)" @@ -5799,1025 +5947,1050 @@ msgstr "Valor Padrão" msgid "Default Parameter Value" msgstr "Valor Padrão do Parâmetro" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Peças" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN deve corresponder ao padrão regex {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Não é permitido duplicar IPN em configurações de partes" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Peças não podem ser atribuídas a categorias estruturais!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nome da peça" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "É um modelo" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Esta peça é uma peça modelo?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Esta peça é variante de outra peça?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Descrição da peça (opcional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Palavras chave" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Palavras-chave para melhorar a visibilidade nos resultados da pesquisa" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Categoria da Peça" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Revisão de peça ou número de versão" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revisão" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Onde este item é armazenado normalmente?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Validade Padrão" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Estoque Mínimo" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Nível mínimo de estoque permitido" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Unidade de medida para esta peça" -#: part/models.py:1254 +#: part/models.py:1258 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:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Esta parte tem rastreamento para itens únicos?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Esta peça pode ser comprada de fornecedores externos?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Esta peça pode ser vendida a clientes?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Esta parte está ativa?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Soma de Verificação da LDM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Soma de verificação da LDM armazenada" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "LDM conferida por" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "LDM verificada no dia" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Criação de Usuário" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Proprietário responsável por esta peça" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Venda múltipla" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Moeda usada para armazenar os cálculos de preços" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Custo Mínimo da LDM" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Custo mínimo das peças componentes" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Custo Máximo da LDM" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Custo máximo das peças componentes" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Custo Mínimo de Compra" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Custo mínimo histórico de compra" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Custo Máximo de Compra" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Custo máximo histórico de compra" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Preço Interno Mínimo" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Custo mínimo baseado nos intervalos de preço internos" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Preço Interno Máximo" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Custo máximo baseado nos intervalos de preço internos" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Preço Mínimo do Fornecedor" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Preço mínimo da peça de fornecedores externos" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Preço Máximo do Fornecedor" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Preço máximo da peça de fornecedores externos" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Custo Mínimo variável" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Custo mínimo calculado das peças variáveis" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Custo Máximo Variável" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Custo máximo calculado das peças variáveis" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Custo Mínimo" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Sobrepor o custo mínimo" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Custo Máximo" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Sobrepor o custo máximo" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Custo total mínimo calculado" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Custo total máximo calculado" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Preço Mínimo de Venda" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Preço mínimo de venda baseado nos intervalos de preço" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Preço Máximo de Venda" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Preço máximo de venda baseado nos intervalos de preço" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Custo Mínimo de Venda" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Preço histórico mínimo de venda" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Custo Máximo de Venda" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Preço histórico máximo de venda" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Peça para Balanço" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Total de Itens" -#: part/models.py:3473 +#: part/models.py:3487 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:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Estoque total disponível no momento do balanço" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Data" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Data de realização do balanço" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Custo Mínimo de Estoque" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Custo mínimo estimado de estoque disponível" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Custo Máximo de Estoque" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Custo máximo estimado de estoque disponível" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Nome de Teste" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Insira um nome para o teste" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Descrição do Teste" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Digite a descrição para este teste" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Requerido" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Este teste é obrigatório passar?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Requer Valor" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Anexo obrigatório" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Selecione a Peça Parental" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sub peça" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Selecionar peça a ser usada na LDM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Quantidade de LDM para este item LDM" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Este item LDM é opcional" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Referência do Item LDM" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Notas do Item LDM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Soma de verificação" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Soma de Verificação da LDM da linha" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validado" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "O item da LDM foi validado" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Obtém herdados" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Quantidade deve ser valor inteiro para peças rastreáveis" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Sub peça deve ser especificada" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Substituir Item da LDM" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Item LDM Parental" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Substituir peça" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Selecionar Peça Relacionada" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Relação duplicada já existe" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Categoria de peça pai" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Sub-categorias" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Moeda de compra deste item de estoque" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Peça Original" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Selecione a peça original para duplicar" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Copiar imagem" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Copiar imagem da peça original" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Copiar LDM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Copiar lista de materiais da peça original" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Copiar Parâmetros" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Copiar dados do parâmetro da peça original" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Copiar Notas" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Copiar imagem da peça original" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Quantidade Inicial de Estoque" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Local Inicial do Estoque" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Especifique o local do estoque inicial para esta Peça" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Selecione o fornecedor (ou deixe em branco para pular)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Selecione fabricante (ou deixe em branco para pular)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Número de Peça do Fabricante" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "A empresa selecionada não é um fornecedor válido" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "A empresa selecionada não é um fabricante válido" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "A peça do fabricante que corresponde a essa MPN já existe" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "A peça do fornecedor que corresponde a essa SKU já existe" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Nome da Categoria" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Produzindo" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Itens de Estoque" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Estoque Total" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Peça duplicada" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Copiar dados iniciais de outra peça" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Estoque inicial" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Criar peça com a quantidade inicial de estoque" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Informações do Fornecedor" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Adicionar informação inicial de fornecedor para esta peça" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Copiar Parâmetros da Categoria" -#: part/serializers.py:948 +#: part/serializers.py:994 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:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Imagem Existente" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Nome de arquivo de uma imagem de peça existente" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "A imagem não existe" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Validar a Lista de Materiais completa" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Pode Produzir" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Preço Mínimo" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Sobrepor valor calculado para preço mínimo" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Moeda do preço mínimo" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Preço Máximo" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Sobrepor valor calculado para preço máximo" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Moeda do preço máximo" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Atualizar" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Atualizar preços desta peça" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Selecionar peça para copiar a LDM" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Remover Dado Existente" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Remova itens LDM existentes antes de copiar" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Incluir Herdados" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Pular Linhas inválidas" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Habilitar esta opção para pular linhas inválidas" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Copiar Peças Substitutas" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Copiar peças de substitutas quando duplicar itens de LDM" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notificação de estoque baixo" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Quantidade a alocar" msgid "Label printing failed" msgstr "Impressão de etiqueta falhou" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "Fornece suporte nativo para códigos de barras" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Impressora de etiquetas PDF do InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Modo de depuração" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Ativar o modo de depuração - retorna HTML bruto em vez de PDF" @@ -7500,7 +7673,7 @@ msgstr "Borda" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Paisagem" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin instalado com sucesso" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin instalado na {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Extensões" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nenhum autor encontrado" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Extensão requer pelo menos a versão {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Extensão requer no máximo a versão {v}" @@ -7884,55 +8070,55 @@ msgstr "Instalação não confirmada" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Recarregamento completo" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Realize um recarregamento completo do registro de plugin" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Forçar recarregamento" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Forçar um recarregamento do registro do plugin, mesmo que já esteja carregado" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Coletar plugins" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Colete plugins e adicione-os ao registro" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Ativar Extensão" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Ativar esta extensão" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Itens" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "Carta" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Nome do modelo" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Padrão de Nome de Arquivo" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtros" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Tamanho da página para relatórios PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Renderizar relatório em orientação paisagem" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Largura [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Largura da etiqueta, em mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Altura da Etiqueta, em mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Recorte" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Relatar arquivo de recorte" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Descrição do arquivo de recorte" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Patrimônio" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Reportar arquivo de ativos" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Descrição do arquivo de ativos" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Selecione o modelo de etiqueta" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de Sério" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Itens instalados" @@ -8248,184 +8438,196 @@ msgstr "Sem resultado (obrigatório)" msgid "No result" msgstr "Nenhum resultado" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "O arquivo não existe" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Arquivo de imagem não encontrado" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "Tag part_image necessita de uma instância de Peça" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "Tag company_image necessita de uma instância de Empresa" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Código da situação" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Localização externa" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Árvore de Peças" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Data de validade antes" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Data de validade depois" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Inativo" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Quantidade obrigatória" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Uma peça válida deve ser fornecida" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "A peça do fornecedor informado não existe" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Tipos de Locais de estoque" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Localização do estoque" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Locais de estoque" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Responsavel" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Selecionar Responsável" @@ -8461,7 +8663,7 @@ msgstr "Selecionar Responsável" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Externo" @@ -8481,274 +8683,282 @@ msgstr "Tipo de Local de Estoque para esta locação" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 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:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "O item não pode pertencer a si mesmo" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Item de Estoque Parental" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Peça base" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Onde está localizado este item de estoque?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Embalagem deste item de estoque está armazenado em" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Instalado em" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Este item está instalado em outro item?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Número de série para este item" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Código do lote para este item de estoque" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Quantidade de Estoque" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Produção de Origem" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Produção para este item de estoque" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Pedido de produção que consumiu este item de estoque" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Pedido de compra Fonte" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Pedido de Compra para este item de estoque" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Destino do Pedido de Venda" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Excluir quando esgotado" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Excluir este item de estoque quando o estoque for esgotado" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Preço de compra unitário único no momento da compra" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Convertido para peça" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Peça não está definida como rastreável" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Quantidade deve ser inteira" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "A quantidade não corresponde aos números de série" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Item em estoque foi reservado para um pedido" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Item em estoque está instalado em outro item" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "item em estoque contem outro(s) items" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Item em estoque foi reservado para outro cliente" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Item no estoque está em produção no momento" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Itens de série não podem ser mesclados" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Item de estoque duplicado" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Itens de estoque devem se referir à mesma peça" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Códigos de estado do estoque devem corresponder" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Observações de entrada" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Deve-se fornecer o valor desse teste" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "O anexo deve ser enviado para este teste" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Resultado do teste" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Valor da saída do teste" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Anexo do resultado do teste" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Notas do teste" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Item Primário" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Inserir número de série para novos itens" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Itens Filhos" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 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:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Insira o número de itens de estoque para serializar" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Local de destino do estoque" -#: stock/serializers.py:735 +#: stock/serializers.py:760 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:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Números de série já existem" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Selecione o item de estoque para instalar" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Quantidade a Instalar" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Insira a quantidade de itens a instalar" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Adicionar nota de transação (opcional)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "A quantidade para instalar deve ser pelo menos 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Item de estoque indisponível" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Peça selecionada não está na Lista de Materiais" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Quantidade a instalar não deve exceder a quantidade disponível" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Local de destino para o item desinstalado" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Código de estado do item estoque" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Selecionar itens de estoque para mudar estados" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Nenhum item de estoque selecionado" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Sub-locais" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Parte deve ser comercializável" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Item é alocado para um pedido de venda" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Item está alocado a um pedido de produção" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Cliente para atribuir itens de estoque" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "A empresa selecionada não é um cliente" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Nodas atribuídas a estoque" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Uma lista de item de estoque deve ser providenciada" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Notas de fusão de estoque" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Permitir fornecedores divergentes" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Permitir estado incompatível" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Ao menos dois itens de estoque devem ser providenciados" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Valor da chave primária do Item Estoque" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Notas da transação de estoque" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Última vez que o token foi usado" msgid "Revoked" msgstr "Revogado" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Permissão definida" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Visualizar" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Permissão para ver itens" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Adicionar" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Permissão para adicionar itens" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Alterar" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Permissões para editar itens" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Excluir" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Permissão para excluir itens" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Administrador" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Pedidos de compra" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Pedidos de vendas" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Pedidos de Devolução" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nome de usuário" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Primeiro Nome" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Sobrenome" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Sua conta foi criada." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Por favor, use a função de redefinir senha para acessar" -#: users/serializers.py:452 +#: users/serializers.py:497 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 636acd20b6..96f9ded308 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint não encontrado" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "A lista de itens ou filtros devem ser fornecidas para operação em massa" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Os itens devem ser fornecidos como lista" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Lista de itens inválida fornecida" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filtros devem ser fornecidos como" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtros inválidos fornecidos" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Todos os filtros devem ser usados apenas como verdadeiro" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Nenhum item corresponde com os critérios fornecidos" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nenhum dado fornecido" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Este campo deve ser único." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "O usuário não tem permissão para visualizar esse modelo" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Quantidade inválida" @@ -112,13 +105,13 @@ msgstr "Informe a data" msgid "Invalid decimal value" msgstr "Valor decimal inválido" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Observações" @@ -131,75 +124,91 @@ msgstr "O valor '{name}' não aparece no formato padrão" msgid "Provided value does not match required pattern: " msgstr "O valor fornecido não corresponde ao padrão exigido: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 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:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Número serial em branco" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Número serial duplicado" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grupo invalido:{group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nenhum número de série foi encontrado" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Remover as \"tags\" HTML deste valor" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Os dados contêm conteúdo de marcação proibido" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Erro de conexão" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "O servidor respondeu com código de estado inválido" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Ocorreu uma exceção" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "O download da imagem excedeu seu tamanho máximo" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "O servidor remoto retornou uma resposta vazia" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "A URL fornecida não é um arquivo de imagem válido" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "A referência deve corresponder ao padrão exigido" msgid "Reference number is too large" msgstr "O número de referência é muito longo" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Escolha inválida" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descrição" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descrição (opcional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Caminho" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomes duplicados não podem existir sob o mesmo parental" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Notas Markdown (opcional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Dados de código de barras" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Dados de código de barras de terceiros" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Hash de código de barras" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash exclusivo de dados de código de barras" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Falha na Tarefa" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Falha na tarefa de trabalho '{f}' em segundo plano após tentativas {n}" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Erro de servidor" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Um erro foi registrado pelo servidor." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Deve ser um número válido" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Moeda" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Selecione a moeda entre as opções disponíveis" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Este campo não pode ser nulo." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Imagem remota" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL do arquivo da imagem remota" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Baixar imagens de URL remota não está habilitado" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Falha ao baixar a imagem da URL remota" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Formato de conteúdo inválido" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Tipo de conteúdo não encontrado" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Chinês (simplificado)" msgid "Chinese (Traditional)" msgstr "Chinês (tradicional)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Atualização disponível" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Uma atualização para o InvenTree está disponível" @@ -553,30 +537,30 @@ msgstr "Unidade física inválida" msgid "Not a valid currency code" msgstr "O código de moeda não é válido" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Situação de pedido" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Produção Progenitora" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Incluir Variáveis" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Incluir Variáveis" msgid "Part" msgstr "Parte" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categoria" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Construção de Ancestrais" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Atribuído a mim" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Atribuído a" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Criado antes" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Criado após" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Tem a data inicial" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Data inicial antes" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Data de início após" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Tem data limite" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Data limite antes" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Data limite depois" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Concluído antes" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Concluído após" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Data Mínima" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Data máxima" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Excluir árvore" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "A compilação deve ser cancelada antes de ser excluída" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumível" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opcional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montagem" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testável" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Pedido pendente" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Alocado" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Em pedido" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordem da compilação" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Local" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Saída" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Ordens de Produções" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "O BOM da montagem não foi validado" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Ordem de compilação não pode ser criada para uma parte inativa" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Ordem de compilação não pode ser criado para uma parte desbloqueada" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Criar ordens só pode ser realizado externamente para partes compráveis" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Usuário ou grupo responsável deve ser especificado" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Parte do pedido de compilação não pode ser alterada" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "A data limite deve ser posterior à data inicial" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referência do pedido de produção" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referência do pedido de produção" msgid "Reference" msgstr "Referência" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Breve descrição da produção (opcional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Selecione a peça para construir" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referência do pedido de venda" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Local de Origem" -#: build/models.py:305 +#: build/models.py:308 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)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "Produção Externa" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Esta ordem de compilação é atendida externamente" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Local de Destino" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Quantidade de Produção" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Número de itens em estoque para produzir" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Itens concluídos" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Número de itens em estoque concluídos" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Progresso da produção" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Código de situação da produção" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Código do lote" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Código do lote para esta saída de produção" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Criado em" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Data inicial da produção" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Data de início agendada para esta ordem de produção" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Data alvo final" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Data de conclusão" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "concluído por" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Usuário que emitiu esta ordem de produção" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsável" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Usuário ou grupo responsável para esta ordem de produção" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Link Externo" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link para URL externa" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Prioridade de Produção" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioridade desta ordem de compilação" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Código do Projeto" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Código do projeto para esta ordem de compilação" -#: build/models.py:686 +#: build/models.py:697 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:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Não é possível concluir o pedido com saídas incompletas" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Um pedido de produção foi concluído" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nenhuma saída de produção especificada" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Saída da produção já está concluída" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Saída da produção não corresponde à Ordem de Produção" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Quantidade deve ser maior que zero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 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:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Item da ordem de produção" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Compilar objeto" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantidade" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Quantidade necessária para o pedido de produção" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Quantidade deve ser 1 para estoque serializado" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "O item do estoque está sobre-alocado" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Item de Estoque" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Origem do item em estoque" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Quantidade do estoque para alocar à produção" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Instalar em" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Destino do Item do Estoque" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Nível de produção" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Nome da Peça" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Saída da Produção" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Esta saída de produção já foi concluída" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Esta saída de produção não está totalmente alocada" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Insira a quantidade para construir a saída de produção" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Quantidade inteira necessária para peças rastreáveis" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Números de Série" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Digite os números de série para saídas de produção" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Local de estoque para saídas de produção" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Alocar Números de Série Automaticamente" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Uma lista de saídas de produção deve ser fornecida" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Local de estoque para saídas eliminadas" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Descartar alocações" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar quaisquer alocações de estoque para saídas eliminadas" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Motivo para eliminar saída(s) de produção" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Local para saídas de produção concluídas" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Aceitar Alocação Incompleta" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Consumir Estoque Alocado" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Remover Saídas Incompletas" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Não permitido" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Aceitar conforme consumido por esta ordem de produção" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Desatribua antes de completar esta ordem de produção" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Alguns itens de estoque foram sobrecarregados" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Aceitar não alocados" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Estoque obrigatório não foi totalmente alocado" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Aceitar Incompleto" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Quantidade de produção requerida não foi concluída" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "A ordem de produção tem ordens de produção secundárias abertas" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Ordem de produção deve estar no estado de produção" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Ordem de produção tem saídas incompletas" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Linha de Produção" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Saída da Produção" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Saída de produção deve indicar a mesma produção" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Item da linha de produção" -#: build/serializers.py:928 +#: build/serializers.py:934 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" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "O item deve estar em estoque" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Alocação de itens precisam ser fornecidos" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Excluir Local" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Excluir itens de estoque desta localização selecionada" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Estoque Intercambiável" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Estoque Substituto" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Permitir alocação de peças substitutas" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Itens opcionais" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Alocar itens BOM opcionais para ordem de produção" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Falha ao iniciar tarefa de alocação automática" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Referência do BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID da parte BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Nome da peça BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Produção" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Fornecedor da Peça" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Quantidade Alocada" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Referência da produção" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Nome da Categoria" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Rastreável" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Herdado" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Item BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Em Produção" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Agendado para produção" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Estoque Externo" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Estoque Disponível" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Estoque Substituto Disponível" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Estoque de Variantes Disponível" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "Em Espera" msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Concluído" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Estoque obrigatório para a ordem de produção" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Ordem de produção {build} requer estoque adicional" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Ordem de produção vencido" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Ordem de produção {bo} está atrasada" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "É um link" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "É um arquivo" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "O usuário não tem permissão para deletar esses anexos" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "O usuário não tem permissão para deletar esse anexo" @@ -1551,798 +1539,822 @@ msgstr "Nenhum código de moeda válido fornecido" msgid "No plugin" msgstr "Sem extensão" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Rótulo de código do projeto" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Atualizado" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Tempo da última atualização" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Atualizado Por" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Usuário que atualizou este objeto pela última vez" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Código único do projeto" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Descrição do projeto" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Chave de configurações" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Valor da Configuração" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Valor deve ser um valor booleano" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Valor deve ser um número inteiro" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "O valor deve ser um número válido" -#: common/models.py:893 +#: 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:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "A frase senha deve ser diferenciada" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Usuário" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Quantidade de Parcelamentos" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Preço" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Preço unitário na quantidade especificada" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Ponto final" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Ponto final em qual o webhook foi recebido" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Nome para este webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Ativo" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Este webhook está ativo" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Ficha" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Ficha para acesso" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Secreto" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Segredo compartilhado para HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID da Mensagem" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Identificador exclusivo desta mensagem" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Servidor" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Servidor do qual esta mensagem foi recebida" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Cabeçalho" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Cabeçalho da mensagem" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Corpo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Corpo da mensagem" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Ponto do qual esta mensagem foi recebida" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Trabalhado em" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "O trabalho desta mensagem foi concluído?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Título" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Publicado" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Resumo" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Lida" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Esta notícia do item foi lida?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Arquivo de imagem" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Tipo modelo de destino para esta imagem" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "ID do modelo de destino para esta imagem" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Unidade Personalizada" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "O símbolo da unidade deve ser único" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Nome da unidade deve ser um identificador válido" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Nome da unidade" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Símbolo de unidade opcional" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definição" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definição de unidade" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Anexo" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Arquivo ausente" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Link externo não encontrado" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Categoria de Modelo" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Tipo modelo de destino para esta imagem" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Selecione arquivo para anexar" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Comentário" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Comentário de anexo" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Data de envio" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Data em que o arquivo foi enviado" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Tamanho do arquivo" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Tamanho do arquivo em bytes" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Categoria de modelo especificado inválido para anexo" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Status Referência Definido" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Conjunto de status estendido com este estado personalizado" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Chave lógica" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Valor" -#: common/models.py:2114 +#: common/models.py:2196 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:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Nome do estado" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que será exibida no frontend" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Cor" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Cor que será exibida no frontend" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modelo" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Modelo que este estado está associado a" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Modelo deve ser selecionado" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "A chave deve ser selecionada" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Chave lógica deve ser selecionada" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "A chave deve diferir da chave lógica" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Uma classe de estado de referência válida deve ser fornecida" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Lista de Seleção" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Listas de Seleção" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Nome da lista de seleção" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Descrição da lista de seleção" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Esta lista de seleção está bloqueada?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Esta lista de seleção pode ser usada?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Extensão de origem" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Extensão que fornece a lista de seleção" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Série de Origem" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Série opcional identificando a fonte usada para esta lista" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Entrada Padrão" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Entrada padrão para esta lista de seleção" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Criado em" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Data e hora em que a lista de seleção foi criada" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Última Atualização" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "Data e hora da última atualização da lista de seleção" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Entrada na lista de seleção" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Entradas na Lista de Seleção" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Lista de seleção à qual esta entrada pertence" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Valor da entrada da lista de seleção" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Rótulo para a entrada da lista de seleção" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Descrição da entrada da lista de seleção" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Esta entrada da lista de seleção está ativa?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Nome do Parâmetro" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Unidades" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Caixa de seleção" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Modelo" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Dados" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Anotação" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Campo opcional de notas" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Escaneamento de Código de Barras" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Dados de código de barras" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Usuário que escaneou o código de barras" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Marcador de hora" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Data e hora da verificação do código de barras" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "O endpoint da URL que processou o código de barras" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Dados de contexto para escanear código de barras" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Resposta" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Dados de resposta da verificação de código de barras" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultado" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "O código de barras foi digitalizado com sucesso?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Ocorreu um erro" -#: common/models.py:2961 +#: common/models.py:3071 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." -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "Mensagem de e-mail" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "Mensagens de Email" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Anunciado" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Enviado" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Falhou" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Entregue" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Confirmado" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Entrada" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Saída" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Não responder" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Rastrear Entrega" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Monitorado" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Clique no caminho" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "ID Global" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID do Tópico" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Tópico" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Tópico vinculado para esta mensagem" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Tópico do e-mail" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Tópicos de e-mail" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Chave" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Identificador exclusivo deste tópico" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Iniciado interno" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Este tópico foi iniciado internamente?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Data e hora em que o tópico foi criado" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Data e hora da última atualização do tópico" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Itens Recebidos" @@ -2392,1235 +2404,1303 @@ msgstr "É indicado se a configuração é substituída por uma variável de amb msgid "Override" msgstr "Substituir" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Está em execução" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Tarefas Pendentes" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tarefas Agendadas" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tarefas com Falhas" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID da Tarefa" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ID Único da Tarefa" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Congelar tempo" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Nome da tarefa" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Função" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Nome da função" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumentos da tarefa" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Argumentos de Palavra-chave" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Argumentos Palavra-chave da Tarefa" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Nome do arquivo" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Categoria de Modelo" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista de seleção bloqueada" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Sem Grupo" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "URL do site está bloqueada por configuração" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Reinicialização necessária" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Uma configuração que requer uma reinicialização do servidor foi alterada" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migrações pendentes" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Número de migrações pendentes na base de dados" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Códigos de aviso ativos" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Um dicionário dos códigos de aviso ativos" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "ID da instância" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Identificador exclusivo para esta instância do InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Anúncio ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Anuncie a ID da instância do servidor na informação de estado do servidor (não autenticado)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Nome da Instância do Servidor" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Descritor de frases para a instância do servidor" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Usar nome da instância" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Usar o nome da instância na barra de título" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Restringir a exibição 'sobre'" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Mostrar 'sobre' modal apenas para superusuários" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Nome da empresa" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Nome interno da Empresa" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL de Base" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL de base para instância do servidor" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Moeda Padrão" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Selecione a moeda base para cálculos de preços" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Moedas Suportadas" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Lista de códigos de moeda suportados" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Intervalo de Atualização da Moeda" -#: common/setting/system.py:265 +#: 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dias" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Extensão de Atualização de Moeda" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Extensão de Atualização de Moeda a utilizar" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Baixar do URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Permitir baixar imagens remotas e arquivos de URL externos" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Limite de tamanho para baixar" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Tamanho máximo permitido para download da imagem remota" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Usuário-agente utilizado para baixar da URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Permitir a substituição de imagens e arquivos usados baixados por usuário-agente (deixar em branco por padrão)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validação rigorosa de URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Exigir especificação de esquema ao validar URLs" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Atualizar Intervalo de Verificação" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Frequência para verificar atualizações (defina como zero para desativar)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Backup Automático" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Ativar cópia de segurança automática do banco de dados e arquivos de mídia" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Intervalo de Backup Automático" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Especificar o número de dia entre as cópias de segurança" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Intervalo para Excluir da Tarefa" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Os resultados da tarefa no plano de fundo serão excluídos após um número especificado de dias" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Intervalo para Excluir do Registro de Erro" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Registros de erros serão excluídos após um número especificado de dias" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Intervalo para Excluir de Notificação" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Notificações de usuários será excluído após um número especificado de dias" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Intervalo de Exclusão de e-mail" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Mensagens de e-mail serão excluídas após um determinado número de dias" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Proteger o Log de E-mail" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Evitar exclusão de entradas de registros de e-mail" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Suporte aos códigos de barras" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Ativar suporte a leitor de código de barras na interface web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Armazenar Resultados do Código de Barras" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Armazenar a verificação do código de barras no banco de dados" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Contagem máxima de códigos de barras" -#: common/setting/system.py:376 +#: 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" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Atraso na entrada de código de barras" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Tempo de atraso de processamento de entrada de barras" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Suporte a webcam com código de barras" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Permitir a verificação de códigos de barras via webcam no navegador" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Código de barras Exibir Dados" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Exibir dados do código de barras no navegador como texto" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Extensão de geração de códio de barras" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revisões de peças" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Ativar campo de revisão para a Peça" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Somente Revisão da Assembleia" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Permitir revisões apenas para peças de montagem" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Permitir a exclusão da Assembleia" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Padrão de expressão regular para correspondência de Parte IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Permitir Duplicação IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que várias peças compartilhem o mesmo IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Permitir Edição IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Copiar dados da LDM da Peça" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Copiar Dados de Parâmetro da Peça" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Copiar Dados Teste da Peça" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Copiar Parâmetros dos Modelos de Categoria" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Peças são modelos por padrão" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Componente" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Comprável" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Peças são compráveis por padrão" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Comercializável" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Peças vão vendíveis por padrão" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Peças vão rastreáveis por padrão" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Peças são virtuais por padrão" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Mostrar peças relacionadas" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Exibir peças relacionadas com uma peça" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Dados Iniciais de Estoque" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Dados Iniciais de Fornecedor" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Formato de Exibição do Nome da Peça" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formato para exibir o nome da peça" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Ícone de Categoria de Peça Padrão" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de Casas Decimais do Preço" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Máximo Casas Decimais de Preço" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Usar Preços do Fornecedor" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Substituir Histórico de Compras" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Usar Preços do Item em Estoque" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Idade do preço do Item em Estoque" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Usar Preço Variável" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir preços variáveis nos cálculos de valores gerais" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Apenas Ativar Variáveis" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Atualização automática dos preços" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Intervalo de Reconstrução de Preços" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Preços Internos" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Habilitar preços internos para peças" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Substituição de preço interno" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Habilitar Impressão de Etiqueta" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Ativar impressão de etiqueta pela interface da internet" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI da Imagem na Etiqueta" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Ativar Relatórios" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Ativar geração de relatórios" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Modo de depuração" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Gerar relatórios em modo de depuração (saída HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Registro de erros" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Registrar erros que ocorrem ao gerar relatórios" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Tamanho da página" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Tamanho padrão da página PDF para relatórios" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Forçar Unidades de Parâmetro" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Seriais Únicos Globais" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Excluir Estoque Esgotado" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Modelo de Código de Lote" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Validade do Estoque" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Ativar função de validade de estoque" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Vender estoque expirado" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Permitir venda de estoque expirado" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Tempo de Estoque Inativo" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Produzir Estoque Vencido" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Permitir produção com estoque vencido" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Controle de propriedade do estoque" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Ativar controle de propriedade sobre locais e itens de estoque" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Ícone padrão do local de estoque" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Mostrar Itens de Estoque Instalados" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Exibir itens de estoque instalados nas tabelas de estoque" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Verificar LDM ao instalar itens" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Permitir Fora de Transferência" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Produção" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Exigir proprietário responsável" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Um proprietário responsável deve ser atribuído a cada pedido" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Requer Parte Ativa" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Impedir a criação de ordem para partes inativas" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Exigir parte bloqueada" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Impedir criação de pedidos para peças desbloqueadas" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Exigir validade, BOM" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Exigir pedidos secundários fechados" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Pedido de Produção Externo" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Ativar funcionalidade de pedido de construção externa" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Bloquear Até Passagem de Testes" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Ativar Pedidos de Devolução" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Devolução" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Modelo necessário para gerar campo de referência do Pedido de Devolução" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Editar os Pedidos de Devolução Concluídos" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Venda" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Envio Padrão de Pedidos de Venda" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Editar os Pedidos de Vendas concluídos" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como concluídos" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Modelo de Referência de Pedidos de Compras" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Editar Pedidos de Compra Concluídos" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Converter Moeda" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Completar automaticamente os pedidos de Compra" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Ativar senha esquecida" -#: common/setting/system.py:925 +#: common/setting/system.py:954 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Ativar cadastro" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Ativar SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Ativar SSO na página de acesso" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Ativar registro SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Ativar sincronização de grupo SSO" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Chave de grupo SSO" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Mapa do grupo SSO" -#: common/setting/system.py:966 +#: 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 "Um mapeamento de grupos de SSO para grupos locais de InvenTree. Se o grupo local não existir, será criado." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Remover grupos fora do SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email obrigatório" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Exigir do usuário o e-mail no cadastro" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Auto-preencher usuários SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Enviar email duplo" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Senha duas vezes" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "No registro pedir aos usuários duas vezes pela senha" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Domínios permitidos" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupo no cadastro" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Forçar AMF" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Os usuários devem usar uma segurança multifatorial." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Verificar extensões na inicialização" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Verificar por atualizações de extensão" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Ativar integração URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Ativar extensão para adicionar rotas URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Ativar integração de navegação" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Ativar extensões para integrar à navegação" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Ativar integração com aplicativo" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Ativar extensões para adicionar aplicativos" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Ativar integração com agendas" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Ativar extensões para executar tarefas agendadas" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Ativar integração de eventos" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Ativar extensões para responder a eventos internos" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Ativar integração de interface" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Ativar extensões para integrar na interface do usuário" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Ativar integração com o e-mail" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Ativar extensão para processar e-mails de saída/entrada" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Ativar códigos de projeto" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Ativar códigos de projeto para rastrear projetos" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Excluir Locais Externos" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Período de contagem automática" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Exibir nomes completos dos usuários" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Exibir Perfis de Usuário" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Exibir Perfis de Usuários em sua página de perfil" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Ativar Dados da Estação de Teste" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Receber relatório de erros" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Receber notificações para erros do sistema" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Últimas máquinas de impressão utilizadas" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Todos os modelos" @@ -3965,365 +4061,369 @@ msgstr "A peça está ativa" msgid "Manufacturer is Active" msgstr "Fabricante está ativo" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "A peça do Fornecedor está ativa" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "A peça interna está ativa" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "O fornecedor está Ativo" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Empresa" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Tem estoque" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Empresas" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Descrição da empresa" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Descrição da empresa" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Página Web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL do Site da empresa" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Número de telefone" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Número de telefone do contato" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Endereço de e-mail do contato" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Contato" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Ponto de contato" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link para informações externas da empresa" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Esta empresa está ativa?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "É um cliente" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Você vende itens para esta empresa?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "É fornecedor" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Você compra itens desta empresa?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "É fabricante" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Esta empresa fabrica peças?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Moeda padrão utilizada para esta empresa" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "CNPJ" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "CNPJ da empresa" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Endereço" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Endereços" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Selecione a Empresa" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Título do endereço" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Título descrevendo a entrada do endereço" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Endereço Principal" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Definir como endereço principal" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Linha 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Linha de endereço 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Linha 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Linha de endereço 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "CEP" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Cidade/Região" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Cidade CEP / região" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Estado/Provincia" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Estado ou Província" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "País" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "País do endereço" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Notas de envio por correio" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Notas para o envio da transportadora" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Notas de envio interno" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Notas de envio para uso interno" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link para as informações do endereço (externo)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Fabricante da peça" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Peça base" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Selecionar peça" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Selecionar fabricante" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "NPF" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Número de Peça do Fabricante" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Descrição da peça do fabricante" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Unidades de pacote devem ser maior que zero" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornecedor" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Selecione o fornecedor" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Unidade de reserva de estoque fornecedor" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Esta parte de fornecedor está ativa?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Selecionar peça do fabricante" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Descrição da peça fornecedor" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "preço base" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Taxa mínima (ex.: taxa de estoque)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Embalagem" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Embalagem de peças" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Quantidade de embalagens" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "múltiplo" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Pedido múltiplo" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Quantidade disponível do fornecedor" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Disponibilidade Atualizada" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Data da última atualização de dados disponíveis" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Parcelamento de Preço do Fornecedor" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Moeda padrão utilizada para este fornecedor" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Nome da Empresa" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Em Estoque" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Ocorreu um erro ao exportar os dados" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 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:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "O campo já está mapeado para uma coluna de dados" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "A coluna não existe no arquivo de dados" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "O campo não existe no modelo de destino" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "O campo selecionado é somente leitura" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Importar Sessão" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Campo" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Coluna" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Índice de fileira" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Dados da linha original" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Erros" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Válido" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Número de cópias para cada rótulo" msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Desconhecido" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupo" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Referência do Pedido" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Pendente" @@ -4728,7 +4828,7 @@ msgstr "Pendente" msgid "Has Project Code" msgstr "Tem código do projeto" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Criado por" @@ -4764,57 +4864,69 @@ msgstr "Data Prevista Antes" msgid "Target Date After" msgstr "Data Prevista Antes" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Tem Preço" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Concluído Antes" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Concluído Após" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Pedido de Produção Vencido" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Pedido" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Pedido Completo" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Peça Interna" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Pedido pendente" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Concluído" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Possui Envio" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Pedido de Compra" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Pedido de Compra" msgid "Sales Order" msgstr "Pedido de Venda" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Preço Total" msgid "Total price for this order" msgstr "Preço total deste pedido" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Moeda do Pedido" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Moeda para este pedido (deixe em branco para usar o padrão da empresa)" msgid "This order is locked and cannot be modified" msgstr "Este pedido está bloqueado e não pode ser modificado" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "O contato não corresponde à empresa selecionada" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Data inicial deve ser anterior à data limite" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Descrição do pedido (opcional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Selecione o código do projeto para este pedido" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link para página externa" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Data inicial" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Data de início programada para esta encomenda" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data Prevista" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Data de emissão" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Dia que o pedido foi feito" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Usuário ou grupo responsável para este pedido" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Ponto de contato para este pedido" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Endereço da empresa para este pedido" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Referência do pedido" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Situação" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Estado do pedido" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Empresa da qual os itens estão sendo encomendados" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Referencia do fornecedor" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Código de referência do pedido fornecedor" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "recebido por" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Dia que o pedido foi concluído" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Destino" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Destino para os itens recebidos" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Fornecedor de peça deve corresponder a fornecedor da OC" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Quantidade deve ser um número positivo" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Empresa para qual os itens foi vendidos" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Situação do Pedido de Venda" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Referência do Cliente " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Código de Referência do pedido do cliente" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Data de envio" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "O pedido já está completo" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "O pedido já está cancelado" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Apenas um pedido aberto pode ser marcado como completo" -#: order/models.py:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "O pedido está bloqueado e não pode ser modificado" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Quantidade do item" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Referência do Item em Linha" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Observações do Item de Linha" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Descrição do item de linha (opcional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Contexto adicional para esta linha" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Preço Unitário" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Item de linha de pedido de compra" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "A peça do fornecedor deve corresponder ao fornecedor" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Pedido de produção deve ser marcada como externa" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "Os pedidos de produção só podem ser vinculados a partes de montagem" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "Criar parte do pedido deve combinar a parte do item de linha" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Fornecedor da Peça" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Recebido" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Número de itens recebidos" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Preço de Compra" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Preço unitário de compra" -#: order/models.py:1978 +#: order/models.py:2056 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:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Linha Extra do Pedido de Compra" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Item de Linha de Pedido de Vendas" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Preço de Venda" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Preço de venda unitário" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Quantidade enviada" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Envio do Pedido de Venda" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Data do envio" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Data de Entrega" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Data da entrega do envio" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Verificado por" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Usuário que verificou este envio" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envio" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Número do Envio" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Número de rastreio" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informação de rastreamento" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Quantidade alocada deve ser maior que zero" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Linha" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Item" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Copiar linhas" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Duplicar Pedido" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "ID do pedido inválido" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "O pedido não pode ser cancelado" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Mesclar Itens" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Código (SKU)" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Número Interno da Peça" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Nome Interno da Peça" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Código de barras lido" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Código de barras já está em uso" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Itens Alocados" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: 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:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "Rejeitado" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Categoria da Peça" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Categorias de Peça" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Local Padrão" @@ -5778,7 +5926,7 @@ msgstr "Palavras-chave padrão para peças nesta categoria" msgid "Icon" msgstr "Ícone" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ícone (opcional)" @@ -5799,1025 +5947,1050 @@ msgstr "Valor Padrão" msgid "Default Parameter Value" msgstr "Valor Padrão do Parâmetro" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Peças" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Nome da peça" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "É um modelo" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Descrição da peça (opcional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Palavras-chaves" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Categoria da Peça" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Validade Padrão" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Estoque Mínimo" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Criação de Usuário" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Data" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Modelos de teste só podem ser criados para partes testáveis" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Obrigatório" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sub peça" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Itens de Estoque" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Estoque Total" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Estoque Inicial" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Atualizar" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Ignorar Linhas Inválidas" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Habilite essa opção para ignorar linhas inválidas" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "Expirou {abs(days_diff)} dias atrás" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dias" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "Margem" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Paisagem" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtros" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Arquivo Modelo" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Mesclar" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Largura [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Largura da Etiqueta, em mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Altura da Etiqueta, em mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Estoque mínimo" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Estoque máximo" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Responsável" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Selecionar Responsável" @@ -8461,7 +8663,7 @@ msgstr "Selecionar Responsável" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Permissão para exibir itens" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Adicionar" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Permissão para adicionar itens" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Alterar" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Permissões para editar itens" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Excluir" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Permissão para excluir itens" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Interno" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Convidado" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Idioma" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Idioma preferencial para o usuário" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Tema" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "Widgets" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Nome de Exibição" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Nome de exibição escolhido para o usuário" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Cargo" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Mensagem de status do usuário" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Tipo de Usuário" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organização" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nome de usuário" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Primeiro Nome" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Primeiro nome do usuário" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Sobrenome" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Sobrenome do usuário" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Endereço de e-mail do usuário" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superusuário" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Somente um superusuário pode ajustar este campo" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Senha" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Senha do usuário" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "Você não tem permissão para criar usuários" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Sua conta foi criada." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 c6befeaa17..b3db2e6899 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Criteriul API final nu a fost găsit" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Lista articolelor sau filtrelor trebuie să fie prevăzută pentru operaţiune în vrac" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Articolele trebuie să fie furnizate ca o listă" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Listă de articole nevalidă furnizată" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filtrele trebuie furnizate ca dicționar" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Filtre furnizate nevalide" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Toate filtrele trebuie folosite doar cu adevărat" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Niciun articol nu corespunde criteriilor furnizate" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Nu sunt furnizate date" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Acest câmp trebuie să fie unic." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Utilizatorul nu are permisiunea de a vedea acest model" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Cantitate furnizata nevalida" @@ -112,13 +105,13 @@ msgstr "Enter Date" msgid "Invalid decimal value" msgstr "Valoare zecimală nevalidă" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notițe" @@ -131,75 +124,91 @@ msgstr "Valoarea '{name}' nu apare în formatul modelului" msgid "Provided value does not match required pattern: " msgstr "Valoarea furnizată nu se potrivește cu modelul necesar: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Nu se pot serializa mai mult de 1000 de elemente odată" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Golire șir de numere de serie" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Număr de serie duplicat" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grup nevalid: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Niciun număr de serie găsit" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Elimină tag-urile HTML din această valoare" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Datele conţin conţinut de marcaje interzis" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Eroare de conexiune" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Serverul a răspuns cu un cod de stare invalid" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Excepție apărută" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Serverul a răspuns cu o valoare de Content-Length invalidă" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Dimensiunea imaginii este prea mare" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Descărcarea imaginii a depăşit dimensiunea maximă" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Serverul la distanță a returnat un răspuns gol" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "URL-ul furnizat nu este un fișier imagine valid" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Referința trebuie să corespundă modelului necesar" msgid "Reference number is too large" msgstr "Numărul de referință este prea mare" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Alegere invalidă" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Nume" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Descriere" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Descriere (opțional)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Cale" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplicate nume nu poate exista sub acelaşi părinte" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Note Markdown (opțional)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Date Cod de Bare" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Date coduri de bare terțe" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Date Cod de Bare" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Hash unic al codului de bare" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Cod de bare existent găsit" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Eroare sarcină" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Sarcina lucrătorului de fundal '{f}' a eșuat după {n} încercări" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Eroare de server" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "A fost înregistrată o eroare de către server." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Trebuie sa fie un număr valid" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Monedă" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Selectați moneda din opțiunile disponibile" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Acest câmp nu poate fi null." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Valoare invalidă" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Imagini de la distanţă" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL-ul imaginii la distanţă" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Descărcarea imaginilor din URL-ul de la distanţă nu este activată" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Descărcarea imaginii din URL-ul de la distanță a eșuat" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Format de tip de conținut nevalid" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Tipul de conținut nu a fost găsit" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Tipul de conținut nu se potrivește cu mixin necesar clasei" @@ -537,11 +521,11 @@ msgstr "Chineză (simplificată)" msgid "Chinese (Traditional)" msgstr "Chineză (tradițională)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Actualizare disponibilă" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "O actualizare pentru InvenTree este disponibilă" @@ -553,30 +537,30 @@ msgstr "Unitate fizică nevalidă" msgid "Not a valid currency code" msgstr "Nu este un cod valutar valid" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Starea comenzii" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Construcție părinte" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "İnclude variante" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "İnclude variante" msgid "Part" msgstr "Piesă" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Categorie" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Ancestor Build" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Alocate mie" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Atribuit către" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Creat înainte de" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Creat după" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Are data de începere" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Data de început înainte de" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Data de incepere după" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Are dată țintă" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Data de început înainte de" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Data de incepere după" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Finalizat înainte de" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Finalizat după" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Dată min" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Dată maximă" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Exclude arbore" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Construcția trebuie anulată înainte de a putea fi ștearsă" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Consumabile" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opţional" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Asamblate" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Urmarit" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testabilă" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Comandă restantă" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Alocate" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Consumat" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Pe comandă" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 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:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Locatie" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Ieșire" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Comenzi de Producție" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "BOM-ul nu a fost validată" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Utilizator sau grup responsabil trebuie specificat" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Piesa din comanda de producție nu poate fi schimbata" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Data țintă trebuie să fie după data de început" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referință comandă producție" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referință comandă producție" msgid "Reference" msgstr "Referinţă" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Scurtă descriere a construcției (opțional)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "Comanda de producție pentru care această construcție este alocată" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Selectează piesa pentru construit" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referință comandă de vânzare" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "Comanda de vânzare pentru care această construcție este alocată" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Locație sursă" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Construcție externă" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Această comandă de producție este îndeplinită extern" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Locul destinației" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Selectaţi locaţia unde vor fi stocate elementele complete" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Cantitatea construirii" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Numărul de articole de stoc pentru producție" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Articole finalizate" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Numărul de articole din stoc care au fost finalizate" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Stare producției" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Cod status producție" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Cod lot" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Cod de lot pentru această producție" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Data creării" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Data începerii construcției" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Data de început programată pentru această comandă de construcție" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Data finalizării țintă" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." -msgstr "" +msgstr "Data țintă pentru finalizarea construcției. Construcția va fi depășită după această dată." -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" -msgstr "" +msgstr "Data completării" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" -msgstr "" +msgstr "finalizat până la" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" -msgstr "" +msgstr "Emis de" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" -msgstr "" +msgstr "Utilizatorul care a emis această comandă de producție" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" -msgstr "" +msgstr "Responsabil" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" -msgstr "" +msgstr "Utilizatorul sau grupul responsabil pentru această comandă de producție" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" -msgstr "" +msgstr "Link extern" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" -msgstr "" +msgstr "Link către URL-ul extern" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" -msgstr "" +msgstr "Prioritate de construire" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" -msgstr "" +msgstr "Prioritatea acestei comenzi de producție" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Cod proiect" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Cod de proiect pentru această comandă de construcție" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Nu se poate finaliza construcția comenzii cu versiuni deschise" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Nu se poate completa comanda de producție cu rezultate incomplete" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" -msgstr "" +msgstr "Nu s-a putut descărca sarcina pentru a finaliza alocarea construcției" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" -msgstr "" +msgstr "A fost finalizată o comandă de producție {build}" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" -msgstr "" +msgstr "A fost finalizată o comandă de producție" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" -msgstr "" +msgstr "Numerele de serie trebuie furnizate pentru piesele urmăribile" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" -msgstr "" +msgstr "Nu este specificată nicio ieșire de producție" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" -msgstr "" +msgstr "Construcția este deja finalizată" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" -msgstr "" +msgstr "Construcția nu se potrivește cu Comanda de producție" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" -msgstr "" +msgstr "Cantitatea trebuie să fie mai mare decât zero" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" -msgstr "" +msgstr "Cantitatea nu poate fi mai mare decât cantitatea de ieşire" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" -msgstr "" +msgstr "Construcția nu a trecut toate testele necesare" -#: build/models.py:1189 build/serializers.py:591 +#: build/models.py:1202 build/serializers.py:597 #, python-brace-format msgid "Build output {serial} has not passed all required tests" -msgstr "" +msgstr "Construcția {serial} nu a trecut toate testele necesare" -#: build/models.py:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "Stocurile alocate sunt încă în producţie" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" -msgstr "" +msgstr "Nu se poate finaliza parțial o construcție cu elemente alocate" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" -msgstr "" +msgstr "Element linie comandă de producție" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" -msgstr "" +msgstr "Construiește obiectul" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" -msgstr "" +msgstr "Cantitate" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" -msgstr "" +msgstr "Cantitatea necesară pentru comanda de producție" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" -msgstr "" +msgstr "Cantitatea de stoc consumată" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" -msgstr "" +msgstr "Articolul contruit trebuie să specifice o ieșire de construcție, deoarece piesa principală este marcată ca urmăribilă." -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" -msgstr "" +msgstr "Articolul din stoc selectat nu se potrivește cu linia BOM" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "Cantitatea alocată trebuie să fie mai mare decât zero" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" -msgstr "" +msgstr "Cantitatea trebuie sa fie 1 pentru stoc serializat" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" -msgstr "" +msgstr "Cantitate alocata ({q}) nu trebuie sa depaseasca cantitatea disponibila de stoc ({a})" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" -msgstr "" +msgstr "Articolul din stoc este supra alocat" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" -msgstr "" +msgstr "Articol Stoc" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" -msgstr "" +msgstr "Locație articol stoc" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" -msgstr "" +msgstr "Cantitatea de stoc alocată pentru construcție" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" -msgstr "" +msgstr "Instalează în" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" -msgstr "" +msgstr "Destinație articol in stoc" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" -msgstr "" +msgstr "Nivel de construcție" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" -msgstr "" +msgstr "Numele Piesei" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" -msgstr "" +msgstr "Rezultat de construcție" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" -msgstr "" +msgstr "Producția nu corespunde cu producția-mamă" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" -msgstr "" +msgstr "Componenta de ieșire nu corespunde componentei din comanda de producție" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" -msgstr "" +msgstr "Această producție este deja finalizată" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" -msgstr "" +msgstr "Această producție nu este alocată integral" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" -msgstr "" +msgstr "Introduceți cantitatea pentru producția de ieșire" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" -msgstr "" +msgstr "Număr de serie" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" -msgstr "" +msgstr "Nu este permisă" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" -msgstr "" +msgstr "Acceptați nealocat" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" -msgstr "" +msgstr "Acceptați Incomplet" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" -msgstr "" +msgstr "Linie de construcție" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" -msgstr "" +msgstr "Rezultatul construirii" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" -msgstr "" +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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" -msgstr "" +msgstr "Nume piesă BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" -msgstr "" +msgstr "Producție" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" -msgstr "" +msgstr "Nume Categorie Piesă" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" -msgstr "" +msgstr "În Producţie" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" -msgstr "" +msgstr "Stoc extern" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" -msgstr "" +msgstr "Stoc disponibil" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" -msgstr "" +msgstr "Stoc de înlocuire disponibil" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1479,59 +1463,63 @@ msgstr "" #: 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 msgid "Pending" -msgstr "" +msgstr "În așteptare" #: build/status_codes.py:12 msgid "Production" -msgstr "" +msgstr "Producție" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 #: order/status_codes.py:81 msgid "On Hold" -msgstr "" +msgstr "Suspendat" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 #: order/status_codes.py:84 msgid "Cancelled" -msgstr "" +msgstr "Anulat" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" -msgstr "" +msgstr "Finalizat" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" -msgstr "" +msgstr "Comandă de producție restantă" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" -msgstr "" +msgstr "Comanda de producție {bo} este în întârziere" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" -msgstr "" +msgstr "Etichetă Cod Proiect" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" -msgstr "" +msgstr "Descrierea proiectului" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" -msgstr "" +msgstr "Utilizatorul sau grupul responsabil pentru acest proiect" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" -msgstr "" +msgstr "Valoarea nu trece verificările de validare" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" -msgstr "" +msgstr "Utilizator" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" -msgstr "" +msgstr "Preț" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" -msgstr "" +msgstr "Preț unitar la cantitatea specificată" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" -msgstr "" +msgstr "Punct final" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" -msgstr "" +msgstr "Punctul final la care acest webhook este primit" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" -msgstr "" +msgstr "Nume pentru acest webhook" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" -msgstr "" +msgstr "Activ" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" -msgstr "" +msgstr "Este acest webhook activ" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" -msgstr "" +msgstr "Token-ul" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" -msgstr "" +msgstr "Token pentru acces" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" -msgstr "" +msgstr "Secret" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" -msgstr "" +msgstr "Host" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" -msgstr "" +msgstr "Host de la care acest mesaj a fost primit" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" -msgstr "" +msgstr "Id-ul" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" -msgstr "" +msgstr "Titlu" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" -msgstr "" +msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" -msgstr "" +msgstr "Publicată" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" -msgstr "" +msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" -msgstr "" +msgstr "Rezumat" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" -msgstr "" +msgstr "Citit" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" -msgstr "" - -#: common/models.py:1769 -msgid "Image file" -msgstr "" +msgstr "A fost citită această știre?" #: common/models.py:1781 +msgid "Image file" +msgstr "Fișier imagine" + +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" -msgstr "" +msgstr "Unitate personalizată" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" -msgstr "" +msgstr "Numele unității trebuie să fie un identificator valid" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" -msgstr "" +msgstr "Numele unității" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" -msgstr "" +msgstr "Comentariu" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" -msgstr "" +msgstr "Comentariu atașament" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" -msgstr "" +msgstr "Data încărcării" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" -msgstr "" +msgstr "Numele statului" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" -msgstr "" +msgstr "Descrierea listei de selecție" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" -msgstr "" +msgstr "Descrierea parametrului" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" -msgstr "" +msgstr "Numele acțiunii" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" -msgstr "" +msgstr "Nume funcție" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" -msgstr "" +msgstr "Nume fișier" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" -msgstr "" +msgstr "Nume Instanţă Server" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 -msgid "Use instance name" -msgstr "" - #: common/setting/system.py:227 +msgid "Use instance name" +msgstr "Utilizaţi numele instanţei" + +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 -msgid "Company name" +#: common/setting/system.py:239 +msgid "Show superuser banner" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 +msgid "Company name" +msgstr "Denumire companie" + +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" -msgstr "" +msgstr "Versiune Componente" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 -msgid "Batch Code Template" -msgstr "" - #: common/setting/system.py:700 -msgid "Template for generating default batch codes for stock items" +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:704 +#: 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 "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 +msgid "Batch Code Template" +msgstr "Șablon Cod lot" + +#: common/setting/system.py:713 +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 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "" +msgstr "Necesită Titularul Responsabil" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "" +msgstr "Titularul responsabil trebuie să fie atribuit fiecărei comenzi" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Comenzi externe de producție" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" -msgstr "" +msgstr "Blochează până la trecerea testelor" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" -msgstr "" +msgstr "Previne ca ieșirile de construcție să fie finalizate până când toate testele necesare trec" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" -msgstr "" +msgstr "Comenzile de vânzare marcate ca expediate vor fi finalizate automat, ocolind starea \"expediate\"" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" +#: common/setting/system.py:953 +msgid "Enable password forgot" +msgstr "Activează parola uitată" -#: common/setting/system.py:958 -msgid "SSO group key" -msgstr "" +#: 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 "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" -msgstr "" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "Parola de două ori" + +#: 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 "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: 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" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 -msgid "Company description" -msgstr "" - #: company/models.py:153 -msgid "Description of the company" -msgstr "" +msgid "Company description" +msgstr "Descrierea Companiei" -#: company/models.py:159 +#: company/models.py:154 +msgid "Description of the company" +msgstr "Descrierea companiei" + +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" -msgstr "" +msgstr "Descrierea piesei de la producător" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" -msgstr "" +msgstr "Descrierea piesei furnizorului" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4718,9 +4818,9 @@ msgstr "" #: order/api.py:130 msgid "Order Reference" -msgstr "" +msgstr "Id comandă" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" -msgstr "" +msgstr "Descrierea comenzii (opțional)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 -msgid "User or group responsible for this order" +msgid "Updated At" msgstr "" -#: order/models.py:517 +#: order/models.py:515 +msgid "User or group responsible for this order" +msgstr "Utilizatorul sau grupul responsabil pentru această comandă de producție" + +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" -msgstr "" +msgstr "Descrierea elementului de rând (opțional)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" -msgstr "" +msgstr "Introduceți codul lotului pentru articolele din stoc primite" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" -msgstr "" +msgstr "Este versiune" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" -msgstr "" +msgstr "Are Versiuni" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" -msgstr "" +msgstr "Descrierea piesei (opțional)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" -msgstr "" +msgstr "Versiunea" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" -msgstr "" +msgstr "Este aceasta parte o versiune a unei alte părți?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" -msgstr "" +msgstr "Versiune Din" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" -msgstr "" +msgstr "Responsabil pentru acest capitol" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" -msgstr "" +msgstr "Descriere test" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" -msgstr "" +msgstr "Introduceți descrierea pentru acest test" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" -msgstr "" +msgstr "Este necesar acest test pentru a trece?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" -msgstr "" +msgstr "Versiunea" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "Descrierea piesei" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7061,7 +7234,7 @@ msgstr "" #: plugin/base/ui/serializers.py:49 msgid "Feature Description" -msgstr "" +msgstr "Descrierea funcției" #: plugin/base/ui/serializers.py:54 msgid "Feature Icon" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7154,7 +7327,7 @@ msgstr "" #: plugin/builtin/events/auto_issue_orders.py:32 msgid "Automatically issue build orders on the assigned target date" -msgstr "" +msgstr "Eliberarea automată a comenzilor de producție la data țintă atribuită" #: plugin/builtin/events/auto_issue_orders.py:38 msgid "Auto Issue Purchase Orders" @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" -msgstr "" +msgstr "Descrierea șablonului" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" -msgstr "" +msgstr "Număr versiune (creșteri automate)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" -msgstr "" +msgstr "Descrierea detaliată a fișierului" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" +msgstr "Descriere fișier Asset" + +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8161,7 +8351,7 @@ msgstr "" #: report/templates/report/inventree_build_order_report.html:152 msgid "Issued By" -msgstr "" +msgstr "Emis de" #: report/templates/report/inventree_purchase_order_report.html:15 msgid "Supplier was deleted" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8202,7 +8392,7 @@ msgstr "" #: report/templates/report/inventree_sales_order_shipment_report.html:47 #: templates/email/stale_stock_notification.html:20 msgid "Batch" -msgstr "" +msgstr "Lot" #: report/templates/report/inventree_stock_location_report.html:97 msgid "Stock location items" @@ -8215,14 +8405,14 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" #: report/templates/report/inventree_stock_report_merge.html:111 #: report/templates/report/inventree_test_report.html:167 msgid "Serial" -msgstr "" +msgstr "Serie" #: report/templates/report/inventree_test_report.html:97 msgid "Test Results" @@ -8234,7 +8424,7 @@ msgstr "" #: report/templates/report/inventree_test_report.html:129 msgid "Pass" -msgstr "" +msgstr "Ok" #: report/templates/report/inventree_test_report.html:131 msgid "Fail" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" -msgstr "" +msgstr "Proprietar" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,280 +8683,288 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" -msgstr "" +msgstr "Codul lotului pentru acest element din stoc" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" #: stock/serializers.py:85 msgid "Generated batch code" -msgstr "" +msgstr "Cod lot generat" #: stock/serializers.py:94 msgid "Select build order" @@ -8762,15 +8972,15 @@ msgstr "" #: stock/serializers.py:103 msgid "Select stock item to generate batch code for" -msgstr "" +msgstr "Selectați articolul din stoc pentru a genera codul de lot" #: stock/serializers.py:112 msgid "Select location to generate batch code for" -msgstr "" +msgstr "Selectaţi locaţia pentru a genera codul de lot pentru" #: stock/serializers.py:121 msgid "Select part to generate batch code for" -msgstr "" +msgstr "Selectați articolul pentru a genera codul de lot pentru" #: stock/serializers.py:130 msgid "Select purchase order" @@ -8778,7 +8988,7 @@ msgstr "" #: stock/serializers.py:137 msgid "Enter quantity for batch code" -msgstr "" +msgstr "Introduceți cantitatea pentru codul de lot" #: stock/serializers.py:163 msgid "Generated serial number" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Nume utilizator" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Prenumele" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Prenumele utilizatorului" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" -msgstr "" +msgstr "Parolă" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" -msgstr "" +msgstr "Parolă pentru utilizator" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" +msgstr "Suprascrie avertismentul cu privire la regulile parolei" + +#: users/serializers.py:417 +msgid "Staff" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" -msgstr "" +msgstr "Vă rugăm să utilizați funcția de resetare a parolei pentru a vă autentifica" -#: users/serializers.py:452 +#: users/serializers.py:497 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 f1a52a50c8..34094be307 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Конечная точка API не обнаружена" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Список элементов или фильтров должен быть указан для массовых операций" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Элементы должны быть представлены в виде списка" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Предоставлен недопустимый список элементов" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Фильтры должны быть предоставлены в виде словаря" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Не верные фильтры" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Все фильтры будут использоваться с параметром True" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Нет элементов, соответствующих заданным критериям" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Данные не предоставлены" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Поле должно быть уникальным." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "У пользователя недостаточно прав для просмотра этой модели!" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Невозможно преобразовать {original} в {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "недопустимое количество" @@ -112,13 +105,13 @@ msgstr "Введите дату" msgid "Invalid decimal value" msgstr "Не верное десятичное значение" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Заметки" @@ -131,75 +124,91 @@ msgstr "Значение '{name}' отсутствует в формате ша msgid "Provided value does not match required pattern: " msgstr "Предоставленное значение не соответствует требуемому формату: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Одновременно можно сериализовать только 1000 элементов" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Пустая строка серийного номера" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Повторяющийся серийный номер" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Недопустимая группа: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Диапазон группы {group} превышает допустимое количество ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Серийных номеров не найдено" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Количество уникальных серийных номеров ({n}) должно быть равно ({q})" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Удалить HTML теги из этого значения" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Данные содержат недопустимую разметку" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Ошибка соединения" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Сервер ответил неверным кодом статуса" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Произошло исключение" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Сервер ответил неверным значением Контент-Длина" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Изображение слишком большое" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Загрузка изображения превышен максимальный размер" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Удаленный сервер вернул пустой ответ" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Предоставленный URL не является допустимым файлом изображения" @@ -207,11 +216,11 @@ msgstr "Предоставленный URL не является допусти msgid "Log in to the app" msgstr "Войти в приложение" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Электронная почта" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Вы должны включить двухфакторную аутентификацию, прежде чем делать что-нибудь еще." @@ -255,133 +264,108 @@ msgstr "Ссылка должна соответствовать шаблону msgid "Reference number is too large" msgstr "Номер ссылки слишком большой" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Неверный выбор" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Название" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Описание" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Описание (необязательно)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Путь" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Повторяющиеся имена не могут существовать под одним и тем же родителем" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Записи о скидке (необязательно)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Данные штрихкода" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Данные стороннего штрих-кода" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Хэш штрих-кода" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Уникальный хэш данных штрих-кода" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Обнаружен существующий штрих-код" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Задача не удалась" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Фоновый процесс '{f}' после {n} попыток завершился с ошибкой" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Ошибка сервера" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Сервер зарегистрировал ошибку." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Должно быть действительным номером" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Валюта" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Выберите валюту из доступных вариантов" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Это поле не может быть пустым." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Неверное значение" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Удаленное изображение" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "ССЫЛКА файла изображения на удаленном сервере" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Загрузка изображений с удаленного URL-адреса не включена" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Не удалось загрузить изображение из URL адреса" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Неверный формат типа содержимого" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "Тип содержимого не найден" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "Тип содержимого не соответствует требуемому классу миксина" @@ -537,11 +521,11 @@ msgstr "Китайский (Упрощенный)" msgid "Chinese (Traditional)" msgstr "Китайский (Традиционный)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Доступно обновление" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "Доступно обновление для InvenTree" @@ -553,30 +537,30 @@ msgstr "Неверная физическая единица" msgid "Not a valid currency code" msgstr "Неверный код валюты" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Статус заказа" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Родительский заказ на производство" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Включая варианты" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Включая варианты" msgid "Part" msgstr "Деталь" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Категория" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Родительская сборка" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Назначено мне" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Назначено" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Создано до" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Создано после" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Есть дата начала" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Дата начала до" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Дата начала после" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Есть целевая дата" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Целевая дата до" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Целевая дата после" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Завершено до" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Завершено после" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "Минимальная дата" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Максимальная дата" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Исключить дерево" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Заказ на производство должен быть отменен перед удалением" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Расходник" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Необязательно" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Сборная деталь" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Отслеживается" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Тестируемая" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Невыполненные заказы" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Зарезервировано" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Потреблено" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "В заказе" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Заказ на производство" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Расположение" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Выход" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Фильтрация по идентификатору исходящей складской позиции. Используйте 'null', чтобы найти несмонтированные элементы сборки." -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Заказы на производство" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Сборка BOM не подтверждена" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Порядок сборки не может быть создан для неактивной части" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "Порядок сборки не может быть создан для разблокированной части" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Заказ на сборку может быть помечен сторонним только для покупных деталей" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Должен быть указан ответственный пользователь или группа" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Деталь заказа на производства не может быть изменена" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Целевая дата должна быть после даты начала" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Ссылка на заказ на производство" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Ссылка на заказ на производство" msgid "Reference" msgstr "Номер" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Краткое описание заказа на производство (необязательно)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "Заказ на производство, которому принадлежит этот заказ на производство" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Выберите деталь для производства" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Ссылка на заказ" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Заказ на продажу, которому принадлежит этот заказ на производство" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Место хранения комплектующих" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Выберите место хранения для этого заказа на производство (оставьте пустым, чтобы взять с любого места на складе)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "Сторонняя сборка" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Этот заказ на сборку выполнен сторонней компанией" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Место хранения результата" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Выберите место хранения завершенных элементов" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Количество производимых деталей" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Количество складских позиций для производства" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Произведенные детали" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Количество складских позиций, которые были произведены" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Статус заказа на производство" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Код статуса заказа на производство" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Код партии" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Код партии для продукции" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Дата создания" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Дата начала сборки" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Запланированная начальная дата этого заказа на сборку" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Целевая дата завершения" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Целевая дата для заказа на производства. Заказ будет просрочен после этой даты." -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Дата завершения" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "выполнено" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Создано" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Пользователь, создавший этот заказ на производство" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ответственный" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Пользователь, ответственный за этот заказ на производство" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Внешняя ссылка" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Ссылка на внешний URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Приоритет производства" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Приоритет этого заказа на производство" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Код проекта" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Код проекта для этого заказа на производство" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Невозможно завершить заказ на сборку при наличии открытых дочерних сборок" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Невозможно завершить заказ на сборку при незавершенных выходах" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "Не удалось выгрузить задачу для распределения на сборку" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Заказ на производство {build} был завершен" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Заказ на производство был завершен" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "Для отслеживаемых деталей должны быть указаны серийные номера" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Продукция не указана" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Продукция уже произведена" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Продукция не совпадает с заказом на производство" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Количество должно быть больше нуля" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Количество не может быть больше количества продукции" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "Выход сборки не прошёл все необходимые тесты" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "Выделенные на складе товары все еще находятся в производстве" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "Невозможно частично завершить выход сборки с распределёнными элементами" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Номер позиции для производства" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Объект производства" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Количество" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Требуемое количество для заказа на производство" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Количество израсходованного запаса" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Элемент производства должен указать продукцию, как главную деталь помеченную как отслеживаемая" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Выбранная складская позиция не соответствует позиции в BOM" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "Резервируемое количество должно быть больше нуля" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Количество должно быть 1 для сериализованных запасов" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Резервируемое количество ({q}) не должно превышать доступное количество на складе ({a})" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Складская позиция перераспределена" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Складская позиция" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Исходная складская позиция" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Количество на складе для производства" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Установить в" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Целевая складская позиция" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Уровень сборки" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Наименование детали" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Выход Продукции" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Продукция не совпадает с родительским заказом на производство" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Продукция не соответствует детали заказа на производство" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Эта продукция уже помечена как завершенная" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Сырье для этой продукции не полностью зарезервировано" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Введите количество продукции" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Для отслеживаемых деталей должно быть указано целочисленное количество" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Требуется целое количество, так как материал содержит отслеживаемые детали" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Серийные номера" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Введите серийные номера для продукции" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Местоположение склада для результата сборки" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Автоматически выделить серийные номера" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Автоматически зарезервировать необходимые элементы с соответствующими серийными номерами" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Следующие серийные номера уже существуют или недействительны" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Необходимо представить список выхода деталей" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Место хранения для списанной продукции" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Отменить резервирование" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Отменить все резервы запасов для списанной продукции" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Причина списания продукции" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Место хранения для завершенной продукции" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Разрешить неполное резервирование" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Завершить продукцию, даже если остатки не были полностью зарезервированы" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Израсходовать зарезервированные остатки" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "Израсходовать складские позиции, которые были зарезервированы для этой продукции" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Удалить незавершенную продукцию" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Удалить всю незавершенную продукцию" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Запрещено" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Принять как поглощенный этим заказом на производство" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Отменить резерв, до завершения заказа на производство" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Перераспределенные запасы" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Как вы хотите обработать дополнительные складские позиции, назначенные для заказа на производство" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Некоторые складские позиции были перераспределены" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Разрешить не полное резервирование" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Подтвердите, что складские позиции не были полностью зарезервированы для этого заказа на производство" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Необходимые запасы не были полностью зарезервированы" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Разрешить незавершенные производимые детали" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "Допустить, что требуемое кол-во продукции не завершено" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Требуемое количество деталей не было произведено" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Производственный заказ имеет незавершённые дочерние заказы" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Заказ на производство должен быть в стадии выполнения" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Заказ на производство имеет незавершенную продукцию" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Позиция для производства" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Выход продукции" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Продукция должна указывать на тот же производство" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Позиция для производства" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part должна указывать на ту же часть, что и заказ на производство" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Элемент должен быть в наличии" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "Превышено доступное количество ({q})" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "Продукция должна быть указан для резервирования отслеживаемых частей" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Продукция не может быть указана для резервирования не отслеживаемых частей" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Необходимо указать резервируемые элементы" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Место хранения, где будут зарезервированы детали (оставьте пустым, чтобы забрать их из любого места)" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Исключить место хранения" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Исключить складские позиции из этого выбранного места хранения" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Обменный остаток" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Складские позиции в нескольких местах могут использоваться на взаимозаменяемой основе" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Заменить остатки" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Разрешить резервирование замещающих деталей" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Необязательные элементы" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Зарезервировать необязательные позиции BOM для заказа на производство" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Не удалось запустить задачу автораспределения" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Ссылка на спецификацию (BOM)" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID детали в спецификации (BOM)" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Название детали в спецификации (BOM)" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "Установить в" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Сборка" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Деталь поставщика" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Зарезервированное количество" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Ссылка на сборку" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Название категории детали" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Отслеживание" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Унаследованные" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Есть варианты" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Позиция BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "В производстве" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Запланировано к сборке" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Внешний склад" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Доступный запас" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Доступный запас заменителей" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Доступный запас вариантов" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Потреблённое количество превышает выделенное количество" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Дополнительные примечания по расходу запаса" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "Элемент сборки должен ссылаться на правильный заказ на сборку" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Дублирование выделения элемента сборки" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "Строка сборки должна ссылаться на правильный заказ на сборку" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Дублирование выделения строки сборки" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "Должен быть указан хотя бы один элемент или строка" @@ -1495,43 +1479,47 @@ msgstr "Отложен" msgid "Cancelled" msgstr "Отменён" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Завершён" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Необходимый запас для заказа на производство" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Заказ на сборку {build} требует дополнительный запас" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Просроченный заказ сборки" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Заказ на производство {bo} просрочен" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Ссылка" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Файл" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "У пользователя нет прав для удаления этих вложений" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "У пользователя нет прав на удаление этого вложения" @@ -1551,798 +1539,822 @@ msgstr "Не указаны действительные коды валют" msgid "No plugin" msgstr "Нет плагина" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Название кода проекта" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Обновлено" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Временная метка последнего обновления" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Обновлено" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Пользователь, последний раз обновивший этот объект" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Уникальный код проекта" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Описание проекта" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Пользователь или группа, ответственные за этот проект" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Ключ настроек" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Значения настроек" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Выбранное значение не является допустимым" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Значение должно быть булевым" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Значение должно быть целым числом" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Значение должно быть допустимым числом" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Значение не прошло проверку" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Строка ключа должна быть уникальной" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Пользователь" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Скидка распространяется на заданное количество" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Цена" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Цена за единицу для указанного количества" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Конечная точка" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "Конечная точка, на которой принимается этот веб-хук" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Имя для этого веб-хука" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Активный" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Этот веб-хук активен?" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Токен" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Токен для доступа" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Секрет" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Общий ключ для HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID Сообщения" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Уникальный идентификатор этого сообщения" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Хост" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Хост, с которого было получено это сообщение" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Заголовок" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Заголовок этого сообщения" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Тело" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Текст этого сообщения" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Конечная точка, на которую было получено это сообщение" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Работал над" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Работа над этим сообщением завершена?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Код" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Заголовок" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Ссылка" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Опубликовано" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Автор" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Итого" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Читать" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Эта новость была прочитана?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Файл изображения" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Тип целевой модели для этого изображения" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "ID целевой модели для этого изображения" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Пользовательская единица измерения" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Символ единицы должен быть уникальным" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Имя единицы должно быть действительным идентификатором" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Название единицы" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Символ" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Обозначение единицы измерения (необязательно)" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Определение" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Определение единицы измерения" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Вложения" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Файл не найден" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Отсутствует внешняя ссылка" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Тип модели" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Тип целевой модели для изображения" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Выберите файл для вложения" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Комментарий" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Описание вложения" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Дата загрузки" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Дата загрузки файла" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Размер файла" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Размер файла в байтах" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Указан недопустимый тип модели для вложения" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Пользовательское состояние" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Пользовательские состояния" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Группа статусов" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Группа статусов, которая будет дополнена пользовательским состоянием" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Логическое состояние" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "Логическое состояние, соответствующее пользовательскому состоянию в бизнес-логике" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Значение" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Числовое значение, которое будет сохранено в базе данных" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Название состояния" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Метка" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Метка, которая будет отображаться на фронтенде" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Цвет" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Цвет отображения в интерфейсе" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Модель" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Модель, с которой связано это состояние" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Необходимо выбрать модель" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Необходимо выбрать ключ" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Логическое состояние должно быть выбрано" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Ключ должен отличаться от логического ключа" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Должен быть указан корректный класс ссылочного статуса" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "Состояние должно отличаться от других логических состояний выбранного статуса" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "Логическое состояние должно быть из множества логических состояний выбранного статуса" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "Имя должно отличаться от имен эталонного статуса" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Список выбора" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Списки выбора" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Название списка выбора" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Описание списка выбора" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Заблокирована" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Этот список выбора заблокирован?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Можно ли использовать этот список выбора?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Исходный плагин" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Плагин, который предоставляет список выбора" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Исходная строка" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "Необязательная строка, определяющая источник, используемый для этого списка" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Запись по умолчанию" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Вариант по умолчанию для этого списка выбора" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Создано" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Дата и время создания списка выбора" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Последнее обновление" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "Дата и время последнего обновления списка выбора" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Вариант списка выбора" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Варианты списка выбора" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Список выбора, к которому относится данный вариант" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Значение варианта списка выбора" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Метка для элемента списка выбора" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Описание варианта списка выбора" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Активен ли варианта списка выбора?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Шаблон параметра" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Шаблоны параметров" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "У параметров-переключателей не может быть единицы измерения" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "У параметров-переключателей не может быть вариантов" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Варианты должны быть уникальными" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Имя шаблона параметров должно быть уникальным" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Тип целевой модели для этого шаблона параметра" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Название параметра" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Единица измерения" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Физическая единица этого параметра" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Описание параметра" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Переключатель" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Этот параметр является переключателем?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Варианты" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Возможные варианты этого параметра (разделить запятой)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Список выбора для этого параметра" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Включено" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Включен ли этот шаблон параметра?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Параметр" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Параметры" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Недопустимое значение параметра" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Указан неверный тип модели для параметра" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "ID модели" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "ID целевой модели для этого параметра" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Шаблон" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Шаблон параметра" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Данные" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Значение параметра" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Заметка" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Опциональное поле записей" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Сканирование штрихкодов" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Данные штрихкода" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Пользователь, который сканировал штрих-код" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Метка времени" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Дата и время сканирования штрих-кода" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "URL-адрес, обработавший штрихкод" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Контекст" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Контекстные данные для сканирования штрих-кода" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Ответ" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Данные ответа от сканирования штрихкода" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Результат" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Сканирование штрихкода было успешным?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Произошла ошибка" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "Сообщение электронной почты" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "Сообщения электронной почты" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Объявлено" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Отправлено" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Неудача" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Доставлено" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Подтверждено" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Входящее" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Исходящее" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Без ответа" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Отслеживать доставку" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Отслеживать прочтение" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Отслеживать клики" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Глобальный идентификатор" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "Идентификатор этого сообщения (может быть предоставлен внешней системой)" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "ID цепочки" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Идентификатор темы этого сообщения (может быть предоставлен внешней системой)" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Цепочка" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Связанная цепочка для этого сообщения" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Приоритет" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "Цепочка электронной почты" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "Цепочки электронной почты" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Ключ" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "Уникальный ключ для этой цепочки (используется для идентификации цепочки)" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Уникальный идентификатор этой цепочки" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Запущено внутренне" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Эта цепочка была начата внутри?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Дата и время создания цепочки" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Дата и время последнего обновления цепочки" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Полученные элементы" @@ -2392,1235 +2404,1303 @@ msgstr "Указывает, переопределена ли настройка msgid "Override" msgstr "Переопределить" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Запущен" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Ожидающие задачи" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Запланированные задания" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Невыполненные Задачи" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Код задачи" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Уникальный ID задачи" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Заблокировать" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Время блокировки" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Название задачи" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Функция" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Имя функции" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Аргументы" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Аргументы задачи" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Именованные аргументы" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Именованные аргументы задачи" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Имя файла" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Тип модели" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "Пользователь не имеет разрешения создавать или редактировать вложения для этой модели" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "У пользователя нет разрешения на создание или редактирование параметров для этой модели" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Список выбора заблокирован" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Нет группы" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "URL сайта заблокирован настройками" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Требуется перезапуск" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Настройки были изменены, что требует перезапуска сервера" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Ожидаемые миграции" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Количество ожидаемых миграций базы данных" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Активные коды предупреждений" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Словарь активных кодов предупреждений" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "Идентификатор экземпляра" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Уникальный идентификатор для этого экземпляра InvenTree" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "ID объявления" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Сообщить ID экземпляра сервера в информации о состоянии сервера (без аутентификации)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Название сервера" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Текстовое описание сервера" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Название инстанса" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Имя сервера в заголовке" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Ограничить отображение `О...`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Показать `О...` только суперпользователям" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Название компании" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Внутреннее название компании" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Базовая ссылка" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Базовая ссылка для экземпляра сервера" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Валюта по умолчанию" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Выберите базовую валюту для расчета цены" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Поддерживаемые валюты" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Список поддерживаемых кодов валют" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Интервал обновления курса валют" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "Как часто обновлять курс валют (установите \"ноль\", чтобы выключить)" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "дней" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Плагин обновления валют" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Модуль обновления валюты" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Скачать по ссылке" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Разрешить загрузку удаленных изображений и файлов по внешнему URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Ограничение размера загрузки" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Максимально допустимый размер загрузки для удалённого изображения" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-Agent, используемый для загрузки из URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Позволяет переопределить user-Agent, используемый для загрузки изображений и файлов с внешнего URL (оставьте пустым по умолчанию)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Строгая проверка URL-адреса" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Требуется спецификация схемы при проверке URL-адресов" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Интервал проверки обновлений" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Как часто проверять наличие обновлений (установите ноль чтобы выключить)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Автоматическое резервное копирование" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Включить автоматическое резервное копирование базы данных и медиа-файлов" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Интервал резервного копирования" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Укажите количество дней между событиями автоматического резервного копирования" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Интервал удаления задачи" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Результаты фоновых задач будут удалены после указанного количества дней" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Интервал удаления журнала ошибок" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Журналы ошибок будут удалены после указанного количества дней" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Интервал удаления уведомления" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Уведомления пользователя будут удалены после указанного количества дней" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "Интервал удаления электронной почты" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "Сообщения электронной почты будут удалены через указанное количество дней" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "Защитить журнал электронной почты" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "Предотвращать удаление записей журнала электронной почты" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Поддержка штрих-кодов" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Включить поддержку сканера штрих-кодов в веб-интерфейсе" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Сохранять результаты сканирования штрихкодов" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Сохранять результаты сканирования штрихкодов в базе данных" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Максимальное количество сохранённых сканирований штрихкодов" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Максимальное число результатов сканирования штрихкодов для хранения" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Задержка сканирования штрих-кода" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Время задержки обработки штрих-кода" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Поддержка веб-камер штрих-кодов" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Разрешить сканирование штрих-кода через веб-камеру в браузере" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Показать данные штрих-кода" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Отображать данные штрих-кода в браузере в виде текста" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Плагин генерации штрих-кода" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Плагин для использования внутренней генерации данных штрих-кодов" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Ревизия детали" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Включить поле ревизии для элемента" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Только ревизия сборки" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Разрешить ревизии только для сборочных деталей" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Разрешить удаление из заказа" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "Разрешить удаление частей, которые используются в заказе" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Регулярное выражение IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Шаблон регулярного выражения для сопоставления IPN детали" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Разрешить повторяющиеся IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Разрешить нескольким элементам использовать один и тот же IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Разрешить редактирование IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "Разрешить изменение значения IPN при редактировании детали" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Скопировать данные BOM детали" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Копировать данные BOM по умолчанию при дублировании детали" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Скопировать данные параметров детали" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "Копировать данных параметров по умолчанию при дублировании детали" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Скопировать данные тестирования детали" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "Копировать данные тестирования по умолчанию при дублировании детали" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Скопировать параметры по шаблону категории" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Копировать параметры по шаблону категории при создании детали" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "По умолчанию детали являются шаблонами" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "По умолчанию детали могут быть собраны из других компонентов" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Компонент" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "По умолчанию детали могут использоваться в качестве суб-компонентов" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Можно купить" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "По умолчанию детали являются отслеживаемыми" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Можно продавать" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Детали продаются по умолчанию" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "По умолчанию детали являются отслеживаемыми" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Виртуальная" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Детали являются виртуальными по умолчанию" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Показывать связанные детали" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Отображать связанные детали для элемента" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Начальные данные о запасах" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "Разрешить создание начального запаса при добавлении новой детали" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Исходные данные о поставщике" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Разрешить создание исходных данных о поставщике при добавлении новой детали" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Формат отображения детали" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Формат для отображения имени детали" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Значок раздела по умолчанию" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Значок категории по умолчанию (пустой означает отсутствие значка)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Минимальные Цены Десятичные Значки" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Минимальное количество десятичных знаков при отображении данных о ценах" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Макс. Цены десятичные знаки" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Минимальное количество десятичных знаков при отображении данных о ценах" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Использовать цены поставщика" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Включить разницу цен поставщиков при расчетах цен" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Изменить историю покупки" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Ценообразование по историческим заказам на поставку отменяет различия в ценах поставщиков" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Использовать цены из складских позиций" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Использовать расценки из ручного ввода данных о запасах для расчета цен" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Возраст цен складских позиций" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Исключить складские позиции старше указанного количества дней с расчёта цен" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Использовать варианты цен" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Включить разницу цен поставщиков при расчетах цен" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Только Активные Варианты" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Использовать только активные запчасти для расчета стоимости варианта" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Автоматическое обновление цен" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "Автоматически обновлять цены деталей при изменении внутренних данных" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Интервал пересчета цен" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "Количество дней до автоматического обновления цены" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Внутренние цены" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Разрешить внутренние цены для частей" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Переопределение внутренней цены" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "При наличии внутренних цен переопределить ценовой диапазон" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Включить печать этикеток" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Включить печать этикеток из веб-интерфейса" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Изображение меток DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Разрешение DPI при создании файлов изображений для печати этикеток плагинов" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Включить отчеты" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Включить генерацию отчетов" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Режим отладки" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Генерировать отчеты в режиме отладки (вывод HTML)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Журнал ошибок отчета" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Журнал ошибок, которые возникают при создании отчетов" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Размер страницы" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Размер страницы по умолчанию для PDF отчетов" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Принудительное применение единиц измерения параметров" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "Если введены единицы, значения параметра должны соответствовать указанным единицам измерения" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Глобально уникальные серийные номера" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "Серийные номера для складских позиций должны быть уникальными глобально" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Удалить исчерпанный запас" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "Определяет поведение по умолчанию, когда складская позиция заканчивается" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Код партии Шаблона" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Шаблон для создания кодов партии по умолчанию для складских позиций" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Срок годности Запасов" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Включить функцию истечения срока годности" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Использовать просроченные остатки в производстве" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Разрешить продажу просроченных запасов" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Время Залежалости Запасов" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "Количество дней перед тем как складская единица будет считаться просроченной" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Использовать просроченные остатки в производстве" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Разрешить использовать просроченные остатки в производстве" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Контроль за собственными запасами" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Разрешить владельцу контролировать расположение складов и номенклатуры" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Значок местоположения по умолчанию" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Значок местоположения склада по умолчанию (пустой означает отсутствие значка)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Показать установленные складские позиции" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Отображать установленные складские позиции в складских таблицах" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Проверять спецификацию при установке изделий" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Установленные единица хранения должны присутствовать в спецификации для родительской детали" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Разрешить передачу товара, отсутствующего на складе" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Паттерн ссылки заказа на производство" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Поле требуемого паттерна для создания ссылки заказа на производство" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Требовать активную деталь" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Запрещать создание заказов на сборку для неактивных деталей" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Требовать заблокированную деталь" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Запрещать создание заказов на сборку для разблокированных деталей" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Требовать валидную спецификацию" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "Запрещать создание заказов на сборку, пока спецификация не будет подтверждена" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Требовать закрытия дочерних заказов" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "Запрещать завершение заказа на сборку, пока не закрыты все дочерние заказы" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Сторонний заказ на сборку" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Включить функциональность сторонних заказов на сборку" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Блокировать до прохождения тестов" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Запретить вывод сборки до тех пор, пока не пройдут все необходимые тесты" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Включить заказы на возврат" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Включите функцию заказа на возврат в пользовательском интерфейсе" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Шаблон заказа на возврат товара" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Необходимый шаблон для создания поля «Возврат заказа»" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Редактировать завершенные возвратные заказы" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "Разрешить редактирование возвращенных заказов после их завершения" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Шаблон заказа на возврат товара" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Необходимый шаблон для создания поля «Возврат заказа»" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Отгрузка по умолчанию для заказа на продажу" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Включить создание отгрузки по умолчанию для заказов на продажу" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Редактирование завершённых заказов на продажу" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Разрешить редактирование заказов на продажу после их отправки или завершения" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Отгрузка требует проверки" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "Запрещать завершение отгрузок, пока товары не проверены" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Отмечать отправленные заказы как завершённые" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Заказы на продажу, помеченные как отгруженные, будут автоматически завершены, минуя статус 'отгружено'" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "Требуемый шаблон для генерации поля ссылки заказа на закупку" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Редактировать завершённые заказы на закупку" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Разрешить редактирование заказов после их отправки или завершения" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Конвертировать валюту" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "Преобразовывать стоимость товара в базовую валюту при поступлении на склад" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Автоматически выполнять заказы на закупку" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Автоматически отмечать заказы на закупку как завершённые при получении всех позиций" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Включить функцию восстановления пароля" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Включить функцию восстановления пароля на странице входа" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Разрешить регистрацию" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "Включить самостоятельную регистрацию пользователей на странице входа" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Включить SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Включить SSO на странице входа" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Включить регистрацию через SSO" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Включить самостоятельную регистрацию пользователей через SSO на странице входа" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Включить синхронизацию групп через SSO" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Включить синхронизацию групп InvenTree с группами, предоставляемыми IdP" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "Ключ группы SSO" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Имя атрибута группы, предоставленного провайдером идентификации" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Отображение групп SSO" -#: common/setting/system.py:966 +#: 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 "Отображение от групп SSO к локальным группам InvenTree. Если локальная группа не существует, она будет создана." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Удалять группы вне SSO" -#: common/setting/system.py:974 +#: 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 "Удалять ли группы, назначенные пользователю, если они не поддерживаются провайдером идентификации. Отключение этой настройки может привести к проблемам безопасности" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Необходимо указать EMail" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Требовать электронную почту при регистрации" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Автозаполнение пользователей SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Автоматически заполнять данные пользователя из аккаунта SSO" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Написать дважды" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "При регистрации дважды спрашивать адрес электронной почты" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Пароль дважды" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "При регистрации запросить пароль у пользователей дважды" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Разрешенные домены" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Ограничить регистрацию определёнными доменами (через запятую, начиная с @)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Группа при новой регистрации" -#: common/setting/system.py:1014 +#: 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." msgstr "Группа, на которую назначаются новые пользователи при регистрации. Если включена синхронизация группы SSO, эта группа задается только в том случае, если ни одна группа не может быть назначена через IdP." -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Принудительное MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Пользователи должны использовать многофакторную безопасность." -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Проверять плагины при запуске" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Проверять, что все плагины установлены при запуске — включать в контейнерных средах" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Проверка обновлений плагинов" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Включить периодическую проверку обновлений установленных плагинов" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Включить интеграцию URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Разрешить плагинам добавлять маршруты URL" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Включить интеграцию навигации" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Разрешить плагинам интегрироваться в навигацию" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Включить интеграцию приложений" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Разрешить плагинам добавлять приложения" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Включить интеграцию расписаний" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Разрешить плагинам запускать запланированные задачи" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Включить интеграцию событий" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Разрешить плагинам реагировать на внутренние события" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Включить интеграцию интерфейса" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Разрешить плагинам интегрироваться в пользовательский интерфейс" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Включить интеграцию почты" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Разрешить плагинам обрабатывать исходящую и входящую почту" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Включить коды проекта" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Включить коды проекта для отслеживания проектов" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "Включить инвентаризацию" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "Включить функцию записи истории уровней и стоимости запасов" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Исключить сторонний склад" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "Исключить из инвентаризации единицы хранения на внешних складах" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Автоматический период инвентаризации" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "Кол-во дней между автоматических записей инвентаризации" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "Удалять устаревшие записи инвентаризаций" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "Удалять записи инвентаризаций старше N дней" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "Частота удаления записей инвентаризаций" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "Записи инвентаризации будут удалены после N дней" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "Удалять старые записи истории запасов" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "Удалять записи истории запасов старше указанного количества дней" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "Интервал удаления истории запасов" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "Записи истории запасов будут удалены через указанное количество дней" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Показывать полные имена пользователей" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Отображать полные имена пользователей вместо логинов" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Отображать профили пользователей" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Отображать профили пользователей на их странице профиля" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Добавлять данные об испытательном оборудовании" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Добавлять данные об испытательном оборудовании в результаты тестирования" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Включить пинг машин" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Включить периодическую задачу пинга зарегистрированных машин для проверки их статуса" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Получать отчёты об ошибках" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Получать уведомления о системных ошибках" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Последние использованные печатающие машины" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "Сохранять последние использованные печатающие машины для пользователя" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Все модели" @@ -3965,365 +4061,369 @@ msgstr "Деталь активна" msgid "Manufacturer is Active" msgstr "Производитель активен" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Поставляемая деталь активна" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Внутренняя деталь активна" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Поставщик активен" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Производитель" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Компания" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Есть запас" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Компании" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Описание компании" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Описание компании" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Сайт" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Сайт компании" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Телефон" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Контактный телефон" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Электронная почта контакта" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Контакт" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Контактное лицо" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Ссылка на описание компании" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Эта компания активна?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Покупатель" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Является ли компания покупателем?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Поставщик" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Является ли компания поставщиком деталей?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Производитель" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Является ли компания производителем деталей?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Для этой компании используется валюта по умолчанию" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "Налоговый идентификатор" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "Налоговый идентификатор компании" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Адрес" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Адреса" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Выберите компанию" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Заголовок адреса" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Заголовок, описывающий запись адреса" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Основной адрес" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Указать основным адресом" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Строка 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Адресная строка 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Строка 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Адресная строка 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Почтовый индекс" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Город/Регион" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Почтовый индекс, город/регион" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Регион/Область" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Штат или провинция" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Страна" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Страна адреса" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Записи отправления" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Записи для курьера" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Внутренние записи отправления" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Записи отправления для внутреннего пользования" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Ссылка на адресную информацию (внешняя)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Производитель детали" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Базовая деталь" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Выберите деталь" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Выберите производителя" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "Артикул производителя" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Артикул производителя" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "Ссылка на сайт производителя" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Описание детали производителя" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "Единицы измерения упаковки должны быть совместимы с единицами базовой детали" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Единицы упаковки должны быть больше нуля" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Связанная деталь производителя должна ссылаться на ту же базовую деталь" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Поставщик" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Выберите поставщика" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Артикул поставщика" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Является ли эта поставляемая деталь активной?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Выберите производителя части" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Ссылка на сайт поставщика" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Описание детали поставщика" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "базовая стоимость" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Минимальная плата (например, складская)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Упаковка" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Упаковка детали" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Количество в упаковке" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Общее количество, поставляемое в одной упаковке. Оставьте пустым для отдельных элементов." -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "множественные" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Кратность заказа" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Количество, доступное у поставщика" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Доступность обновлена" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Дата последнего обновления данных о доступности" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Ценовой порог поставщика" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Валюта по умолчанию для этого поставщика" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Название компании" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "На складе" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Ценовые пороги" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Произошла ошибка при экспорте данных" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Существующий идентификатор записи в базе данных" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Колонка уже сопоставлена с полем базы данных" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Поле уже сопоставлено с колонкой данных" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "Сопоставление столбцов должно быть связано с корректным сеансом импорта" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Колонка не существует в файле данных" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Поле не существует в целевой модели" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Выбранное поле доступно только для чтения" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Сессия импорта" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Поле" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Колонка" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Номер строки" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Исходные данные строки" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Ошибки" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Корректный" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "Для обновления существующих записей требуется ID." -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Запись с указанным ID не найдена" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Указан недействительный формат ID" @@ -4588,7 +4688,7 @@ msgstr "Количество копий для печати каждой эти msgid "Connected" msgstr "Подключен" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Неизвестно" @@ -4692,7 +4792,7 @@ msgstr "Ключ свойства" msgid "Value of the property" msgstr "Значение свойства" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Группа" @@ -4720,7 +4820,7 @@ msgstr "Максимальное значение для типа прогрес msgid "Order Reference" msgstr "Ссылка на заказ" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Невыполненный" @@ -4728,7 +4828,7 @@ msgstr "Невыполненный" msgid "Has Project Code" msgstr "Есть код проекта" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Создал" @@ -4764,57 +4864,69 @@ msgstr "Целевая дата до" msgid "Target Date After" msgstr "Целевая дата после" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Имеет цену" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Завершено до" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Завершено после" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Сторонний заказ на сборку" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Заказ" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Заказ выполнен" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Внутренняя деталь" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Заказ в ожидании" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Завершённые" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Есть отгрузка" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Заказ на закупку" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Заказ на закупку" msgid "Sales Order" msgstr "Заказ на продажу" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Общая стоимость" msgid "Total price for this order" msgstr "Общая стоимость этого заказа" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Валюта заказа" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "Валюта заказа (оставьте пустым для использования валюты по умолчанию для компании)" @@ -4851,718 +4963,750 @@ msgstr "Валюта заказа (оставьте пустым для испо msgid "This order is locked and cannot be modified" msgstr "Этот заказ заблокирован и не может быть изменён" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Контакт не соответствует выбранной компании" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Дата начала должна быть до целевой даты" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "Адрес не соответствует выбранной компании" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Описание заказа (дополнительно)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Выберите код проекта для этого заказа" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Ссылка на внешнюю страницу" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Начальная дата" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Запланированная начальная дата этого заказа" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Целевая дата" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Ожидаемая дата доставки заказа. После этой даты заказ будет считаться просроченным." -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Дата создания" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Дата выдачи заказа" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Пользователь или группа, ответственная за этот заказ" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Контактное лицо по данному заказу" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Адрес компании по этому заказу" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Ссылка на заказ" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Статус" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Статус заказа на закупку" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Компания, в которой детали заказываются" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Номер у поставщика" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Номер заказа у поставщика" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "получил" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Дата завершения заказа" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Место хранения" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Место хранения для полученных позиций" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Поставщик детали должен совпадать с поставщиком заказа на закупку" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Позиция не соответствует заказу на закупку" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "В позиции отсутствует связанная деталь" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Количество должно быть положительным числом" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Покупатель" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Компания, которой детали продаются" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Статус заказа на продажу" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Ссылка клиента" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Код ссылки на заказ клиента" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Дата отгрузки" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "Отправлено" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Заказ уже выполнен" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Заказ уже отменен" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Только открытый заказ может быть отмечен как завершённый" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Заказ не может быть завершён, так как есть незавершённые отгрузки" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Заказ не может быть завершён, так как есть незавершённые распределения" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "Заказ не может быть завершён, так как есть незавершённые позиции" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Заказ заблокирован и не может быть изменён" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Количество" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Номер позиции" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Записи о позиции" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Целевая дата этой позиции (оставьте пустой, чтобы использовать целевую дату заказа)" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Описание позиции (необязательно)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Дополнительный контекст для этой строки" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Цена за единицу" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Позиция заказа на закупку" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Поставляемая деталь должна соответствовать поставщику" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Заказ на сборку должен быть отмечен как внешний" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "Заказы на сборку могут быть связаны только со сборочными деталями" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "Деталь заказа на сборку должна соответствовать детали позиции" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "Получено" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Количество полученных предметов" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Закупочная цена" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Закупочная цена" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "Внешний заказ на сборку, который будет выполнен этой позицией" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Дополнительная позиция заказа на закупку" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Позиция заказа на продажу" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "Только продаваемые детали могут быть назначены заказу на продажу" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Цена продажи" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Цена последней продажи" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Доставлен" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Отгруженное кол-во" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Отгрузка заказа на продажу" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "Адрес отгрузки должен соответствовать клиенту" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Адрес доставки для этой отгрузки" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Дата отправления" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Дата доставки" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Дата доставки отгрузки" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Проверн" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Пользователь, проверивший эту отгрузку" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Отправление" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Номер отправления" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Номер отслеживания" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Информация об отслеживании доставки" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Номер счета" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Номер ссылки на связанную накладную" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Отгрузка уже отправлена" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Отправка не имеет зарезервированных складских позиций" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "Отгрузка должна быть проверена, прежде чем её можно завершить" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Дополнительная позиция заказа на продажу" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Распределение заказа на продажу" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Складская позиция не была назначена" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "Невозможно зарезервировать складскую позицию в позицию другой детали" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Невозможно распределить запас к позиции без детали" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Количество распределения не может превышать количество на складе" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Резервируемое количество должно быть больше нуля" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Количество должно быть 1 для сериализированных складских позиций" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Заказ на продажу не соответствует отгрузке" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Отгрузка не соответствует заказу на продажу" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Строка" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Ссылка на отгрузку заказа на продажу" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Элемент" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Выберите складскую позицию для резервирования" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Укажите резервируемое количество" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Ссылка на заказ на возврат" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Компания, из которой возвращаются товары" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Статус заказа на возврат" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Позиция заказа на возврат" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Необходимо указать складской элемент" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Количество возврата превышает количество на складе" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Количество возврата должно быть больше нуля" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Недопустимое количество для серийного складского элемента" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Выберите позицию, возвращаемую от клиента" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Дата получения" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "Дата возврата" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Результат" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Результат для этой позиции" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "Стоимость, связанная с возвратом или ремонтом этой позиции" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Дополнительная позиция заказа на возврат" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID заказа" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID заказа для дублирования" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Копировать позиции" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Копировать позиции из исходного заказа" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Копировать дополнительные позиции" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Копировать дополнительные позиции из исходного заказа" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "Позиции" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Завершённые позиции" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Дублировать заказ" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Указать параметры для дублирования этого заказа" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Недействительный ID заказа" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Имя поставщика" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Заказ не может быть отменён" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Разрешить закрывать заказ с незавершёнными позициями" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "В заказе есть незавершённые позиции" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Заказ не открыт" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Автоматическая цена" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Автоматически рассчитывать закупочную цену на основе данных детали поставщика" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Валюта заказа на закупку" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Объединять элементы" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Объединять в одну позицию элементы, у которых одинаковая деталь, место хранения и целевая дата" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Артикул" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Внутренний артикул детали" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Внутреннее название детали" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Необходимо указать поставляемую деталь" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Необходимо указать заказ на закупку" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Поставщик должен соответствовать заказу на закупку" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Заказ на закупку должен соответствовать поставщику" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Позиция" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Выберите место назначения для полученных элементов" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Введите код партии для поступающих складских позиций" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Истекает" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Введите дату истечения срока годности для поступающих складских единиц" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Введите серийные номера для входящих складских позиций" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Переопределить информацию об упаковке для поступающих складских единиц" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Дополнительная заметка для поступающих складских единиц" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Штрих-код" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Сканированный штрих-код" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Штрихкод уже используется" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Необходимо предоставить позиции" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Необходимо указать место назначения" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Предоставленные значения штрихкодов должны быть уникальными" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Отгрузки" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Выполненные отгрузки" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "Зарезервированные позиции" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Валюта цены продажи" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Выделенные элементы" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Информация об отгрузке не предоставлена" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "Позиция не связана с этим заказом" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Количество должно быть положительным" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Введите серийные номера для резервирования" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Отгрузка уже отправлена" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Отгрузка не связана с этим заказом" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "Совпадений для следующих серийных номеров не найдено" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Следующие серийные номера недоступны" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Позиция заказа на возврат" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Позиция не соответствует заказу на возврат" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Позиция уже получена" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "Предметы могут быть получены только по заказам, которые находятся в процессе выполнения" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Количество для возврата" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Валюта цены позиции" @@ -5598,146 +5742,150 @@ msgstr "Возврат" msgid "Reject" msgstr "Отклонён" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Просроченные заказы на закупку" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Заказ на закупку {po} просрочен" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Просроченные заказы на продажу" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Заказ на продажу {so} просрочен" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Просроченный заказ на возврат" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Заказ на возврат {ro} просрочен" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Помечено звёздочкой" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Фильтровать по отмеченным категориям" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Глубина" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Фильтровать по глубине категории" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Верхний уровень" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Фильтровать по категориям верхнего уровня" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Каскад" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Включать подкатегории в отфильтрованные результаты" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Родитель" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Фильтровать по родительской категории" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Исключить подкатегории указанной категории" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Есть результаты" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Является вариантом" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Является ревизией" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Есть ревизии" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Спецификация валидна" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Каскадные категории" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "Если включено, включать элементы в дочерних категориях указанной категории" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Фильтровать по числовому идентификатору категории или литералу 'null'" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "Сборочная деталь активна" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "Отслеживаемая сборочная деталь" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Сборная деталь тестируется" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "Деталь компонента активна" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "Отслеживаемая деталь компонента" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Компонент тестируется" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "Сборочная деталь компонента" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "Виртуальная деталь компонента" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "На складе" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Использования" @@ -5746,11 +5894,11 @@ msgstr "Использования" msgid "Part Category" msgstr "Категория детали" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Категория детали" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Место хранения по умолчанию" @@ -5778,7 +5926,7 @@ msgstr "Ключевые слова по умолчанию для детале msgid "Icon" msgstr "Значок" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Значок (необязательно)" @@ -5799,1025 +5947,1050 @@ msgstr "Значение по умолчанию" msgid "Default Parameter Value" msgstr "Значение параметра по умолчанию" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Детали" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Нельзя удалить параметры заблокированной детали" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Нельзя изменить параметры заблокированной детали" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Нельзя удалить эту деталь, так как она заблокирована" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Нельзя удалить эту деталь, так как она ещё активна" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "Нельзя удалить эту деталь, так как она используется в сборке" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Деталь '{self}' не может быть использована в спецификации для '{parent}' (рекурсивно)" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Деталь '{parent}' используется в спецификации для '{self}' (рекурсивно)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN должен соответствовать регулярному выражению {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Деталь не может быть ревизией самой себя" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Нельзя создать ревизию детали, которая уже является ревизией" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Необходимо указать код ревизии" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Ревизии разрешены только для сборочных деталей" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Нельзя сделать ревизию шаблонной детали" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Родительская деталь должна указывать на тот же шаблон" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Складская позиция с этим серийным номером уже существует" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Дублирующий IPN не разрешён в настройках детали" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Дублирующая ревизия детали уже существует." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Деталь с таким именем, внутренним артикулом и ревизией уже существует." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Детали не могут быть назначены структурным категориям!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Наименование детали" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Шаблон" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Эта деталь является шаблоном?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Эта деталь является разновидностью другой детали?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Разновидность" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Описание детали (необязательно)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Ключевые слова" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "Ключевые слова для улучшения видимости в результатах поиска" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Категория" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Внутренний артикул" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Ревизия или серийный номер детали" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Ревизия" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Является ли эта деталь ревизией другой детали?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Ревизия от" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Где обычно хранится эта деталь?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Срок действия по умолчанию" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "Срок годности (в днях) для складских позиций этой детали" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Минимальный запас" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Минимально допустимый складской запас" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Единицы измерения этой детали" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Может ли эта деталь быть создана из других деталей?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "Может ли эта деталь использоваться для создания других деталей?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Является ли каждый экземпляр этой детали уникальным, обладающим серийным номером?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Можно ли в этой детали записывать результаты тестов?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Может ли эта деталь быть закуплена у внешних поставщиков?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Может ли эта деталь быть продана покупателям?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Эта деталь активна?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Заблокированные детали нельзя редактировать" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "Эта деталь виртуальная, как программный продукт или лицензия?" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "Спецификация подтверждена" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Валидна ли спецификация для этой детали?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Контрольная сумма BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Сохранённая контрольная сумма спецификации" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM проверил" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Дата проверки BOM" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Создатель" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Ответственный владелец этой детали" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Продать несколько" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Валюта, используемая для кэширования расчётов цен" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Минимальная Стоимость BOM" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Минимальная стоимость компонентных деталей" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Максимальная Стоимость BOM" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Максимальная стоимость компонентных деталей" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Минимальная стоимость закупки" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Минимальная историческая стоимость закупки" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Максимальная стоимость закупки" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Максимальная историческая стоимость закупки" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Минимальная внутренняя цена" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Минимальная стоимость на основе внутренних ценовых уровней" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Максимальная внутренняя цена" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Максимальная стоимость на основе внутренних ценовых уровней" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Минимальная цена поставщика" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Минимальная цена детали от внешних поставщиков" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Максимальная цена поставщика" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Максимальная цена детали от внешних поставщиков" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Минимальная стоимость варианта" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Расчётная минимальная стоимость вариантов деталей" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Максимальная стоимость варианта" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Расчётная максимальная стоимость вариантов деталей" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Минимальная Стоимость" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Переопределить минимальную стоимость" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Максимальная Стоимость" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Переопределить максимальную стоимость" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Расчётная общая минимальная стоимость" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Расчётная общая максимальная стоимость" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Минимальная цена продажи" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Минимальная цена продажи на основе ценовых уровней" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Максимальная цена продажи" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Максимальная цена продажи на основе ценовых уровней" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Минимальная стоимость продажи" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Минимальная историческая цена продажи" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Максимальная стоимость продажи" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Максимальная историческая цена продажи" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Деталь для инвентаризации" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Количество элементов" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Количество отдельных складских позиций на момент инвентаризации" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Общий доступный запас на момент инвентаризации" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Дата" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Дата проведения инвентаризации" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Минимальная стоимость запасов" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Оценочная минимальная стоимость имеющихся запасов" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Максимальная стоимость запасов" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Оценочная максимальная стоимость имеющихся запасов" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Цена продажи детали по порогу" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Шаблон теста детали" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Недопустимое имя шаблона — должно содержать хотя бы один буквенно-цифровой символ" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "Шаблоны тестов можно создавать только для тестируемых деталей" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "Шаблон теста с тем же ключом уже существует для детали" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Название теста" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Введите имя для теста" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Ключ теста" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Упрощённый ключ для теста" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Описание теста" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Введите описание для этого теста" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Активен ли данный тест?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Необходим" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Необходимо ли пройти этот тест?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Требуется значение" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "Требуется ли значение для этого теста при добавлении результата?" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Требуются вложения" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "Требуется ли прикреплять вложение в виде файла при добавлении результатов теста?" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Допустимые варианты данного теста(через запятую)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "Пункт спецификации нельзя изменить — сборка заблокирована" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Пункт спецификации нельзя изменить — вариант сборки заблокирован" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Выберите родительскую деталь" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Суб-деталь" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Выбрать деталь для использования в BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Количество элементов в спецификации" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Эта позиция спецификации необязательна" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Эта позиция - расходник (она не отслеживается в заказах на производство)" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Количество для подготовки" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Дополнительное требуемое количество для сборки, учитывающее потери при подготовке" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Потери" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Оценочные потери для сборки, выраженные в процентах (0–100)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Округление до кратности" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Округлять требуемое производственное количество до ближайшего кратного этого значения" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Ссылка на позицию спецификации" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Заметка о позиции в спецификации" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Контрольная сумма" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Контрольная сумма строки спецификации" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Проверен" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Этот пункт спецификации подтверждён" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Наследуется" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Позиция спецификации наследуется разновидностями детали" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Эту позицию можно заменять деталями, которые находятся на складе" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "Для отслеживаемых деталей количество должно быть целым числом" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Необходимо указать поддеталь" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Замена пункта спецификации" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "Деталь для замены не может быть такой же, как основная деталь" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Позиция BOM-родителя" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Замена детали" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Деталь 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Деталь 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Выберите связанную деталь" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Заметка для данной связи" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "Нельзя создать отношение детали с самой собой" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Дублирующее отношение уже существует" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Родительская категория" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Родительская категория деталей" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Подкатегории" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Результаты" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Количество результатов, зарегистрированных по этому шаблону" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Валюта закупки складской позиции" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Файл не является изображением" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Оригинальная деталь" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Выберите исходную деталь для копирования" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Копировать Изображение" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Копировать изображение из исходной детали" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Скопировать BOM" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Копировать спецификацию из исходной детали" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Скопировать параметры" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Копировать данные параметров из исходной детали" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Копировать Записи" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Скопировать записи из оригинальной детали" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Копировать тесты" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "Копировать шаблоны тестов из исходной детали" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Начальное количество на складе" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Задайте начальное количество этой детали на складе. Если количество равно 0, складская позиция не будет добавлена." -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Начальное местоположение запаса" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Укажите начальное местоположение запаса для этой детали" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Выберите поставщика (или оставьте поле пустым, чтобы пропустить)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Выберите поставщика (или оставьте поле пустым, чтобы пропустить)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Артикул производителя" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Выбранная компания не является допустимым поставщиком" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Выбранная компания не является допустимым производителем" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Деталь производителя с данным артикулом уже существует" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Деталь поставщика с данным артикулом уже существует" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Название категории" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Производится" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Количество этой детали, находящееся в производстве" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Оставшееся количество этой детали, запланированное к сборке" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Складские позиции" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Ревизии" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Общий запас" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Нераспределённый запас" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Запас вариантов" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Дублировать деталь" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Копировать начальные данные из другой детали" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Начальный запас" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Создавать деталь с начальным количеством на складе" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Информация о поставщике" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Добавить начальную информацию о поставщике для этой детали" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Копировать параметры категории" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Копировать шаблоны параметров из выбранной категории деталей" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Существующее изображение" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Имя файла существующего изображения детали" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Файл изображения не существует" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Проверить всю спецификацию" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Можно произвести" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Требуется для заказов на сборку" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Выделено для заказов на сборку" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Требуется для заказов на продажу" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Выделено для заказов на продажу" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "Внутренний артикул детали" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "Описание детали" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "Выберите деталь (и любые её варианты) для которой сгенерировать информацию об инвентаризации" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "Выберите категорию (и любые её подкатегории) для которой сгенерировать информацию об инвентаризации" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "Выберите склад, чтобы включить все детали в наличии в указанном складе (включая подразделы)" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "Создать записи инвентаризации" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "Сохранить записи инвентаризации для выбранных деталей" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "Создать отчет" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "Создать отчёт инвентаризации для выбранных деталей" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Минимальная цена" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Переопределить рассчитанное значение минимальной цены" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Валюта минимальной цены" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Максимальная цена" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Переопределить рассчитанное значение максимальной цены" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Валюта максимальной цены" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Обновить" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Обновить цены для этой детали" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Не удалось конвертировать из предоставленных валют в {default_currency}" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Минимальная цена не должна превышать максимальную цену" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Максимальная цена не должна быть меньше минимальной" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Выберите родительскую сборку" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Выберите деталь, которая является компонентом" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Выберите деталь, из которой копировать спецификацию" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Удалить существующие данные" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Удалить существующие пункты спецификации перед копированием" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Включая наследуемые" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Включать пункты спецификации, унаследованные от шаблонных деталей" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Пропустить некорректные строки" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Включите эту опцию, чтобы пропускать недопустимые строки" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Копировать детали-заменители" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Копировать детали-заменители при дублировании пунктов спецификации" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Уведомление о низком уровне запаса" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Доступный запас для {part.name} упал ниже настроенного минимального уровня" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Уведомление о просроченном запасе" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "У вас 1 складская единица приближается к дате истечения срока годности" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "У вас {item_count} складских единиц приближаются к дате истечения срока годности" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Нет даты истечения" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "Истёк {abs(days_diff)} дней назад" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Истекает сегодня" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} дней" @@ -7031,15 +7204,15 @@ msgstr "Количество для распределения" msgid "Label printing failed" msgstr "Печать этикетки не удалась" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Ошибка при выводе этикетки в PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Ошибка при выводе этикетки в HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Нет элементов для печати" @@ -7100,7 +7273,7 @@ msgstr "Предоставляет встроенную поддержку шт #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Уведомление об изменённой детали" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "Для детали `{part.name}` произошло событие `{part_action}`" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "PDF-печать этикеток InvenTree" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Предоставляет встроенную поддержку печати этикеток PDF" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Режим отладки" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Включить режим отладки — возвращает чистый HTML вместо PDF" @@ -7500,7 +7673,7 @@ msgstr "Граница" msgid "Print a border around each label" msgstr "Печатать рамку вокруг каждой этикетки" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Альбомная" @@ -7580,64 +7753,77 @@ msgstr "Предоставляет поддержку сканирования msgid "The Supplier which acts as 'TME'" msgstr "Поставщик, который представляет 'TME'" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "Только пользователи с правами персонала могут управлять плагинами" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Установка плагинов отключена" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Плагин успешно установлен" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Плагин установлен в {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Плагин не найден в реестре" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Плагин не является упакованным" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Имя пакета плагина не найдено" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Только пользователи с правами персонала могут управлять плагинами" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Удаление плагинов отключено" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Плагин нельзя удалить, так как он активен" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Плагин нельзя удалить, так как он обязательный" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Плагин нельзя удалить, так как он является образцом" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Плагин нельзя удалить, так как он встроенный" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Плагин не установлен" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Установка плагина не найдена" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Плагин успешно удалён" @@ -7689,21 +7875,21 @@ msgstr "Пакетный плагин" msgid "Plugin" msgstr "Плагин" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Автор не найден" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Плагин '{p}' несовместим с текущей версией InvenTree {v}" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Плагин требует как минимум версию {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Плагин требует не более версии {v}" @@ -7884,55 +8070,55 @@ msgstr "Установка не подтверждена" msgid "Either packagename or URL must be provided" msgstr "Необходимо указать название пакета или URL" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Полная перезагрузка" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Выполнить полную перезагрузку реестра плагинов" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Принудительная перезагрузка" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Принудительно перезагрузить реестр плагинов, даже если он уже загружен" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Собрать плагины" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Собрать плагины и добавить их в реестр" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Активировать плагин" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Активировать этот плагин" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Обязательный плагин нельзя деактивировать" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Удалить конфигурацию" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Удалить конфигурацию плагина из базы данных" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "Пользователь, для которого применяется эта настройка" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Элементы" @@ -7948,7 +8134,7 @@ msgstr "Плагин не поддерживает печать этикеток msgid "Invalid label dimensions" msgstr "Недопустимые размеры этикетки" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Ни одного допустимого элемента не предоставлено для шаблона" @@ -7972,152 +8158,156 @@ msgstr "Письмо" msgid "Template file with this name already exists" msgstr "Файл шаблона с таким именем уже существует" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Название шаблона" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Описание шаблона" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Номер ревизии (автоматически)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Прикреплять к модели при печати" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Сохранять отчёт как вложение к связанному экземпляру модели при печати" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Шаблон имени файла" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Шаблон для создания имён файлов" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Шаблон включён" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Тип модели шаблона" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Фильтры" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Фильтры запроса шаблона (список ключ=значение через запятую)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Файл шаблона" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Размер страницы для PDF-отчётов" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Рендерить отчёт в альбомной ориентации" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Объединить" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Рендерить один отчёт по выбранным элементам" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Отчёт, сгенерированный из шаблона {self.name}" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Синтаксическая ошибка в шаблоне" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Ошибка при рендеринге отчёта" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Ошибка при генерации отчёта" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Ошибка при объединении выводов отчётов" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Ширина [мм]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Ширина этикетки, задаётся в миллиметрах" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Высота [мм]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Высота этикетки, задаётся в миллиметрах" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Ошибка при печати этикеток" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Сниппет" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Файл фрагмента отчёта" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Описание файла сниппета" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Объект" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Файл ресурса отчёта" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Описание медиафайла" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Выберите шаблон отчёта" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "Список первичных ключей элементов, включаемых в отчёт" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Выберите шаблон этикетки" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Плагин печати" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Выберите плагин для печати этикеток" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Серийный номер" @@ -8215,7 +8405,7 @@ msgstr "Отчет тестирования складской позиции" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Установленные элементы" @@ -8248,184 +8438,196 @@ msgstr "Нет результата (обязательно)" msgid "No result" msgstr "Нет результата" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Файл ресурса не существует" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Файл изображения не найден" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "Тег part_image требует экземпляр детали" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "Тег company_image требует экземпляр компании" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Фильтровать по глубине местоположения" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Фильтровать по местоположениям верхнего уровня" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Включать подместоположения в отфильтрованные результаты" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Основной склад" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Фильтровать по родительскому местоположению" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Название детали (без учёта регистра)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Название детали содержит (без учёта регистра)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Название детали (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "IPN детали (без учёта регистра)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "IPN детали содержит (без учёта регистра)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "IPN детали (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Минимальный запас" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Максимальный запас" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Код статуса" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Внешнее местоположение" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Израсходовано для заказов на сборку" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Установлено в другом складе" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Древо Деталей" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Обновлено до" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Обновлено после" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Инвентаризация до" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Инвентаризация после" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Дата истечения до" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Дата истечения после" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Залежалый" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "Укажите первичный ключ складского элемента, чтобы исключить этот элемент и всех его потомков" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "Каскад местоположений" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "Если включено, включать элементы в дочерних местоположениях данного местоположения" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Фильтровать по числовому идентификатору местоположения или литералу 'null'" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Необходимо указать количество" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Необходимо предоставить действительную деталь" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Указанная поставляемая деталь не существует" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "У поставляемой детали определён размер упаковки, но флаг use_pack_size не установлен" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Не нужно указывать серийные номера для неотслеживаемых деталей" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "Включать установленные" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Если включено, включать результаты тестов для предметов, установленных под данным складским элементом" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "Фильтровать по числовому идентификатору складского элемента" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Складской элемент с ID {id} не существует" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "Включая варианты деталей" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "После" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "До" @@ -8441,19 +8643,19 @@ msgstr "Типы местоположения склада" msgid "Default icon for all locations that have no icon set (optional)" msgstr "Значок по умолчанию для мест хранения с невыбранным значком (необязательно)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Место хранения" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Места хранения" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Владелец" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Выберите владельца" @@ -8461,7 +8663,7 @@ msgstr "Выберите владельца" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Внешний" @@ -8481,274 +8683,282 @@ msgstr "Тип места хранения данного склада" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Вы не можете сделать это место хранение структурным, потому, что некоторые складские позиции уже находятся в нем!" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} не существует" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Необходимо указать деталь" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Складские позиции не могут находиться в структурных местах хранения!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Складская позиция не может быть создана для виртуальных деталей" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Тип детали ('{self.supplier_part.part}') должен быть {self.part}" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "Количество должно быть 1 для элемента с серийным номером" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Серийный номер нельзя задать, если количество больше 1" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Элемент не может принадлежать сам себе" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "Элемент должен иметь ссылку на производство, если is_building=True" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Ссылка на производство не указывает на тот же элемент" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Складская позиция" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Базовая деталь" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "Выберите соответствующего поставщика детали для этой складской позиции" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Где находится эта складская позиция?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Упаковка этой складской позиции хранится в" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Установлено в" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Установлен ли этот элемент в другой элемент?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Серийный номер для этого элемента" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Код партии для этой складской позиции" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Количество на складе" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Исходное производство" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Производства для этой складской позиции" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Поглощен" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Заказ на производство, который поглотил эту складскую позицию" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Исходный заказ на закупку" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Заказ на закупку для этой складской позиции" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Целевой заказ на продажу" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Дата истечения срока годности для складской позиции. Остатки будут считаться просроченными после этой даты" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Удалить при обнулении" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Удалить эту складскую позицию при обнулении складского запаса" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Цена за единицу на момент покупки" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Преобразовано в деталь" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "Количество превышает доступный запас" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Деталь не является отслеживаемой" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Количество должно быть целым числом" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Количество не должно превышать доступный запас ({self.quantity})" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Серийные номера должны быть предоставлены в виде списка" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Количество не соответствует серийным номерам" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "Нельзя назначить запас в структурное местоположение" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Шаблон теста не существует" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Складская позиция была назначена заказу на продажу" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Складская позиция установлена в другую деталь" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Складская позиция содержит другие детали" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Складская позиция была назначена покупателю" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Складская позиция в производстве" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Серийные запасы нельзя объединить" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Дублирующие складские элементы" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Складские позиции должны ссылаться на одну и ту же деталь" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "Складские позиции должны ссылаться на одну и ту же деталь поставщика" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Коды статуса запаса должны совпадать" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "Складской элемент нельзя переместить, так как он отсутствует на складе" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Отслеживание складского элемента" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Заметки к записи" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Результат теста складского элемента" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Для этого теста должно быть указано значение" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Для этого теста требуется загрузить вложения" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Недопустимое значение для этого теста" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Результат тестирования" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Результат выполнения теста" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Вложение с результатом теста" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Заметки о тестировании" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Испытательное оборудование" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "Идентификатор испытательного оборудования, на котором выполнялось тестирование" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Запущен" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Время начала тестирования" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Завершён" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Время окончания тестирования" @@ -8792,246 +9002,246 @@ msgstr "Выберите деталь для генерации серийног msgid "Quantity of serial numbers to generate" msgstr "Количество серийных номеров для генерации" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Шаблон теста для этого результата" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "Для этой детали не найдено подходящего теста" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "Необходимо указать ID шаблона или имя теста" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "Время завершения теста не может быть раньше времени начала" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Родительский элемент" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Родительский складской элемент" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Использовать размер упаковки при добавлении: заданное количество — это количество упаковок" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "Использовать размер упаковки" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Введите серийные номера для новых элементов" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Номер детали поставщика" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Просрочен" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Дочерние элементы" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Отслеживание элементов" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Закупочная цена для этой складской позиции, за единицу или за упаковку" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Введите количество складских позиций для сериализации" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "Складской элемент не предоставлен" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Количество не должно превышать доступный запас ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Целевое место хранения" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Серийные номера не могут присваиваться данной детали" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Серийные номера уже существуют" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Выберите складскую позицию для установки" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Количество для установки" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Введите количество элементов для установки" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Добавить запись к транзакции (необязательно)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Количество для установки должно быть не менее 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Складская позиция недоступна" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Выбранная деталь отсутствует в спецификации" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Количество для установки не должно превышать доступное количество" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Место назначения для демонтированного элемента" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Выберите деталь в которую будет преобразована складская позиция" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "Выбранная деталь не является допустимым вариантом для преобразования" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "Невозможно преобразовать складскую позицию с назначенной деталью поставщика" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Статус складской позиции" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Выберите складские позиции для изменения статуса" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Не выбрано ни одной складской позиции" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Места хранения" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Родительское местоположение запаса" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Деталь должна быть продаваемой" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Элемент распределён в заказ на продажу" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Элемент зарезервирован для заказа на производство" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Покупатель для назначения складских позиций" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Выбранная компания не является покупателем" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Записи о назначенных запасах" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Необходимо предоставить список складских позиций" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Заметки об объединении складских позиций" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Разрешить несоответствие поставщиков" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Разрешить объединение складских позиций с различными поставщиками" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Разрешить несоответствие статусов" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Разрешить объединение складских позиций с различными статусами" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Необходимо предоставить как минимум 2 складские позиции" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Нет изменений" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Первичный ключ складского элемента" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Складской элемент отсутствует на складе" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "Складской элемент уже на складе" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "Количество не должно быть отрицательным" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Заметки об изменении склада" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "Объединить с существующим запасом" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "Объединять возвращённые элементы с существующими складскими элементами, если возможно" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "Следующий серийный номер" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "Предыдущий серийный номер" @@ -9369,227 +9579,247 @@ msgstr "Последнее время использования токена" msgid "Revoked" msgstr "Отозван" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Права доступа" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Вид" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Разрешение на просмотр элементов" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Добавить" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Разрешение на добавление элементов" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Изменить" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Разрешение на редактирование элементов" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Удалить" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Разрешение на удаление элементов" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "Бот" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "Внутренний" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Гость" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Язык" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "Предпочтительный язык пользователя" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Тема" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Настройки веб-интерфейса в формате JSON — не редактировать вручную!" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "Виджеты" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Настройки виджетов панели в формате JSON — не редактировать вручную!" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Отображаемое имя" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "Отображаемое имя пользователя" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "Положение" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "Основное место работы или должность" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "Статусное сообщение пользователя" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "Информация о местоположении пользователя" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "Пользователь активно использует систему" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "Предпочтительная контактная информация пользователя" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Тип пользователя" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "Какого типа этот пользователь?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Организация" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "Основная организация/принадлежность пользователя" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Основная группа" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "Основная группа для пользователя" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Админ" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Заказы на закупку" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Заказы на продажу" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Заказы на возврат" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Логин" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Имя" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Имя пользователя" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Фамилия" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Фамилия пользователя" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Адрес электронной почты пользователя" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Персонал" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Имеет ли этот пользователь права персонала" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Суперпользователь" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Это пользователь является суперпользователем" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Активна эта учетная запись" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "Только суперпользователь может изменить это поле" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Пароль" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "Пароль пользователя" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "Игнорировать предупреждение" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "Игнорировать предупреждение о правилах пароля" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "У вас нет разрешения на создание пользователей" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Ваша учётная запись была успешно создана." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Пожалуйста, используйте функцию сброса пароля для входа" -#: users/serializers.py:452 +#: users/serializers.py:497 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 40289a78a9..83b0cd3b3c 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Slovak\n" "Language: sk_SK\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "" @@ -112,13 +105,13 @@ msgstr "" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 d685a3f30a..e1349bc2fa 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API vmesnik ni najden" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Uporabnik nima dovoljenja pogleda tega modela" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Podana napačna količina" @@ -112,13 +105,13 @@ msgstr "Vnesi datum" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Zapiski" @@ -131,75 +124,91 @@ msgstr "Vrednost '{name}' ni v predpisanem formatu" msgid "Provided value does not match required pattern: " msgstr "Podana vrednost se ujema s predpisanim vzorcem: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Prazno polje serijske številke" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Dvojna serijska številka" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Serijske številke niso najdene" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Odstranite oznako HTML iz te vrednosti" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Napaka povezave" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Odziv serverja: napravilni status kode" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Pojavila se je izjema" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Odziv serverja: napačna dolžina vrednosti" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Prevelika velikost slike" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Prenos slike presegel največjo velikost" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Oddaljeni server vrnil prazen odziv" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Podani URL ni veljavna slikovna datoteka" @@ -207,11 +216,11 @@ msgstr "Podani URL ni veljavna slikovna datoteka" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-pošta" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "Referenca se mora ujemati s vzorcem" msgid "Reference number is too large" msgstr "Referenčna številka prevelika" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Nedovoljena izbira" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Ime" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Opis (opcijsko)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Pot" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Podvojena imena ne morejo obstajati pod istim nadrejenim elementom" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown opombe (neobvezno)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Podatki čtrne kode" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Podatki črtne kode tretje osebe" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Oznaka črtne kode" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Enolična oznaka podatkov črtne kode" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Črtna koda že obstaja" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Napaka strežnika" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Zaznana napaka na strežniku." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Mora biti veljavna številka" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Izberite valuto med razpoložljivimi možnostmi" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Neveljavna vrednost" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Oddaljena slika" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Povezava do oddaljene slike" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Prenos slik iz oddaljene povezave ni omogočen" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kitajščina (poenostavljena)" msgid "Chinese (Traditional)" msgstr "Kitajščina (tradicionalno)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Neveljavna fizična enota" msgid "Not a valid currency code" msgstr "Neveljavna oznaka valute" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Nadrejena izgradnja" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Dodeljeno meni" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Dodeljeno" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Izgradnja mora biti najprej preklicana, nato je lahko izbrisana" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Neobvezno" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montaža" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Sledi" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testno" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Dodeljeno" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Nalog izgradnje" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Nalogi izgradnje" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Sestava BOM ni bila potrjena" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Naveden mora biti odgovorni uporabnik ali skupina" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Referenca naloga izgradnje" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Referenca naloga izgradnje" msgid "Reference" msgstr "Referenca" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Izberite del za izgradnjo" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referenca dobavnica" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Lokacija vira" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Ciljna lokacija" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Izberite lokacijo, kjer bodo končne postavke shranjene" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Količina izgradenj" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Število postavk za izgradnjo" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Končane postavke" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Število postavk zaloge, ki so bile končane" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Status izgradnje" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Koda statusa izgradnje" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Številka serije" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Številka serije za to izgradnjo" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Datum ustvarjenja" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Rok dokončanja" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Datom končanja" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "dokončal" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Izdal" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Uporabnik, ki je izdal nalog za izgradnjo" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odgovoren" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Odgovorni uporabnik ali skupina za to naročilo" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Zunanja povezava" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Zunanja povezava" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Nalog izgradnje {build} je dokončan" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Nalog izgradnej dokončan" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Ni določena izgradnja" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Igradnja je že dokončana" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Izgradnja se ne ujema s nalogom izdelave" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Količina" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Količina za zalogo s serijsko številko mora biti 1" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Preveč zaloge je prestavljene" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Postavka zaloge" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Izvorna postavka zaloge" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Količina zaloge za prestavljanje za izgradnjo" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Inštaliraj v" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Destinacija postavke zaloge" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Izgradnja" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Izgradnja se ne ujema z nadrejeno izgradnjo" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Izhodni del se ne ujema s naročilom sestava" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Ta sestava je že zaključena" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Preklicano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Končano" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Uporabnik" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktivno" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Povezava" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Priloga" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Manjka datoteka" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Manjka zunanja povezava" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Izberite prilogo" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Ime datoteke" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Poslano" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Prestavljena količina mora biti večja od 0" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Uporabniško ime" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Ime" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Ime uporabnika" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Priimek" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Priimek uporabnika" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Email uporabnika" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Osebje" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Ali ima ta uporabnik pravice osebja" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superuporabnik" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Ali je ta uporabnik superuporabnik" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Ali je ta račun aktiven" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Vaš račun je bil ustvarjen." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Za prijavo uporabite funkcijo ponastavitve gesla" -#: users/serializers.py:452 +#: users/serializers.py:497 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 d0c2928edb..71f9ccd0cc 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Serbian (Latin)\n" "Language: sr_CS\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API krajnja tačka nije pronađena" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Lista nevalidiranih stavki" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Dati su neispravni filteri" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Korisnik nema dozvolu za pregled ovog modela" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Isporučena nevažeća količina" @@ -112,13 +105,13 @@ msgstr "Unesite datum" msgid "Invalid decimal value" msgstr "Neispravna decimalna vrednost" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Napomene" @@ -131,75 +124,91 @@ msgstr "Vrednost '{name}' se ne pojavljuje u formatu obrasca" msgid "Provided value does not match required pattern: " msgstr "Navedena vrednost ne odgovara traženom obrascu: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 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:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Serijski broj nije popunjen" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Dupliciraj serijski broj" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Nevažeća grupa: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Nisu pronađeni serijski brojevi" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Uklonite HTML oznake iz ove vrednosti" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Podatak sadrži zabranjen jezički sadržaj" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Greška u povezivanju" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Server je odgovorio nevažećim statusnim kodom" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Došlo je do izuzetka" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Veličina slike je prevelika" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Preuzimanje slike premašilo je maksimalnu veličinu" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Udaljeni server vratio je prazan odgovor" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Navedeni URL nije važeća slikovna datoteka" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-Pošta" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "Referenca mora odgovarati traženom obrascu" msgid "Reference number is too large" msgstr "Broj reference je predugačak" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Nevažeći izvor" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Ime" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Opis (Opciono)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Putanja" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Dvostruka imena ne mogu postojati pod istom nadredjenom grupom" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Zabeleške (Opciono)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Podaci sa barkoda" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Podaci sa barkoda trećih lica" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Heš barkoda" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Jedinstveni hash barkoda" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Postojeći barkod pronađen" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Neuspešan zadatak" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Pozadinski proces '{f}' neuspešan posle {n} pokušaja" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Greška servera" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Server je zabležio grešku." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Mora biti važeći broj" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Odaberite valutu među dostupnim opcijama" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Nevažeća vrednost" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Udaljena slika" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL udaljene slike" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Preuzimanje slika s udaljenog URL-a nije omogućeno" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Neuspešno preuzimanje slike sa udaljene URL" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kineski (Uprošćeni)" msgid "Chinese (Traditional)" msgstr "Kineski (Tradicionalni)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Nevažeća jedinica mere" msgid "Not a valid currency code" msgstr "Nevažeći kod valute" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Status naloga" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Roditeljski proizvod" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Uključi varijante" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Uključi varijante" msgid "Part" msgstr "Deo" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategorija" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Proizvod predaka" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Dodeljeno meni" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Dodeljeno" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Kreirano pre" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Kreirano nakon" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Ciljni datum pre" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Ciljni datum nakon" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Završeno pre" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Završeno nakon" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Ne uključuj stablo" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Potrošni materijal" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Opciono" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Sklapanje" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Praćeno" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Proverljivo" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Neizmirena narudžbina" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Alocirano" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Po narudžbini" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Nalog za izradu" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Lokacija" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Nalozi za izradu" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "BOM za sastavljanje nije potvrđeno" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Odgovorni korisnik ili grupa mora biti određena" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Deo u nalogu za izradu ne može se izmeniti" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Reference naloga za pravljenje" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Reference naloga za pravljenje" msgid "Reference" msgstr "Referenca" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Kratak opis izrade (nije obavezno)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Izaberi deo za izgradnju" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Referenca naloga za prodaju" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Lokacija izvora" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Lokacija odredišta" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Izaberi lokaciju gde će se završene stavke skladištiti" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Količina izgradnje" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Broj stavki za izgradnju" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Kompletirane stavke" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Broj stavki u zalihama koje su kompletirane" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Status izgradnje" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Kod statusa izgradnje" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Kod serije" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Kod izgradnje za ovaj izlaz" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "datum kreiranja" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Datum ciljanog završetka" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Datum završetka" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "kompletirano od " -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "izdato od" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Korisnik koji je izdao nalog za izgradnju" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odgovoran" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Korisnik ili grupa koja je odgovorna za ovaj nalog za izgradnju" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Spoljašnja konekcija" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Link za eksterni URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Prioritet izgradnje" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Prioritet ovog naloga za izgradnju" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Kod projekta" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Kod projekta za ovaj nalog za izgradnju" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Nalog za izgradnju {build} je kompletiran" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Nalog za izgradnju je kompletiran" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Nije određen izlaz izgradnje" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Izlaz izgradnje je već kompletiran" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Izlaz izgradnje se ne slaže sa Nalogom za izgradnju" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Količina mora biti veća od nule" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Stavka porudžbine naloga za izgradnju" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Objekat izgradnje" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Količina" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Potrebna količina za nalog za izgradnju" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Količina mora da bude 1 za zalihe koje su serijalizovane" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Stavka zaliha je prealocirana" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Stavka zaliha" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Izvor stavke zaliha" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Količina zaliha za alociranje za izgradnju" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Ugradi u" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Stavka zaliha odredišta" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Nivo izgradnje" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Ime dela" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Izlaz izgradnje" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Izlaz izgradnje se ne slaže sa nadređenom izgradnjom" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Izlazni deo se ne slaže sa delom Naloga za Izgradnju" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Ovaj izlaz izgradnje je već kompletiran" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Ovaj izlaz izgradnje nije u potpunosti alociran" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Unesi količinu za izlaz izgradnje" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "Brojčana količina potrebna za delove koji mogu da se prate" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serijski brojevi" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Unesi serijske brojeve za izlaz izgradnje" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Lokacija zaliha za izlaz izgradnje" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Automatski alociraj serijske brojeve" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatski alociraj tražene stavke sa odgovarajućim serijskim brojevima" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Sledeći serijski brojevi već postoje ili su neispravni" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Lista izlaza izgradnje se mora obezbediti" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Lokacija zaliha za otpisane izlaze" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Odbaci alokacije" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Odbaci bilo kojiu alokaciju zaliha za otpisane izlaze" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Razlog za otpisane izlaz(e) izgradnje" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Lokacija za završene izlaze izgradnje" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Prihvati nekompletirane Alokacije" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "kompletiraj izlaze ako zalihe nisu u potpunosti alocirane" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Troši alocirane zalihe" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Ukloni nekompletirane izlaze" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Izbriši svei izlaze izgradnje koji nisu kompletirani" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Nije dozvoljeno" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Prihvati kao potrošeno od strane ovog naloga za izgradnju" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Izmesti bre završetka ovog naloga za izgradnju" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Sveukupne izdvojene zalihe" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Neke stavke zaliha su prealocirane" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Prihvati nealocirano" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Tražene zalihe nisu u potpunosti alocirane" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Prihvati nekompletirano" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Traženi broj izgradnji nije kompletan" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Nalog za izgradnju ima otvoren potčinjene naloge za izgradnju" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Nalog za izgradnju mora biti u stanju produkcije" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Nalog za izgradnju ima nekompletne izlaze" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Porudžbina izgradnje" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Izlaz izgradnje" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Izlaz izgradnje mora da referencira istu izgradnju" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Stavka porudžbine za izradu" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Stavka mora da bude u zalihama" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Stavke alociranja se moraju odrediti" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Isključi lokaciju" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Isključi stavke zaliha za ovu selektovanu lokaciju" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Zamenljive zalihe" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Zamenske zalihe" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Dozvoli alociranje delova koji su zamenski" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Opcionalne stavke" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "Alociraj opcione BOM stavke na nalog za izgradnju" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Greška prilikom startovanja auto alociranja" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "Referenca BOM" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "BOM ID dela" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "BOM ime dela" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Deo dobavljača" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Alocirana količina" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Referenca izgradnje" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Ime kategorije dela" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Može da se prati" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Nasleđen" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Dozvoli varijante" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "BOM stavka" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "U proizvodnji" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Spoljašnje zalihe" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Dostupne zalihe" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Dostupne zamenske zalihe" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Dostupne varijante zaliha" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "Na čekanju" msgid "Cancelled" msgstr "Otkazano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Gotovo" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Potrebne su zalihe za nalog izgranje" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Prekoračeni nalog za izgradnju" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Nalog za izgradnju {bo} je sada prekoračen" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "je link" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "je datoteka" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Korisnik nema potrebne dozvole da bi izbrisao ove atačmente" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Korisnik nema dozvolu da izbriše ovaj atačment" @@ -1551,798 +1539,822 @@ msgstr "Nisu obezbeđeni ispravni kodovi valuta" msgid "No plugin" msgstr "Nema dodataka" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Naziv koda projekta" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Ažurirano" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Vreme poslednjeg ažuriranja" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Jedinstveni kod projekta" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Opis projekta" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Korisnik ili grupa odgovorni za ovaj projkat" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Ključ za podešavanje" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Vrednost podešavanja" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "Izabrana vrednost nije ispravna opcija" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Vrednost mora da bude boolean tipa" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Vrednost mora da bude integer tipa" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Vrednost mora biti broj" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Vrednost ne prolazi test ispravnosti" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Tekstualni ključ mora da bude jedinstven" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Korisnik" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Prelomna količina cene" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Cena" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Cena jedinice za određenu količinu" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Krajnja tačka" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Ime ovog zahteva za izmenu stranice" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktivan" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Da li je ovaj zahtev za izmenu aktivan?" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Token za pristup" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Tajna" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Deljena tajna za HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "ID poruke" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Jedinstveni identifikator za ovu poruku" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Računar" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Računar koji je primio ovu poruku" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Zaglavlje" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Zaglavlje ove poruke" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Telo" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Telo ove poruke" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Krajnja tačka na kojoj je ova poruka primljena" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Radilo se na " -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Da li je rad sa ovom porukom završen?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Naslov" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Objavljeno" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Autor" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Rezime" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Čitaj" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Da li je ova stavka vesti pročitana" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Datoteka slike" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Ciljni tip modela za ovu sliku" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "Ciljni ID modela za ovu sliku" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Posebna jedinica" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Simbol jedinice mora biti jedinstven" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Ime jedinice mora da bude ispravan identifikator" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Ime jedinice" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Simbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Opcioni simbol jedinice" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definicija" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Definicija jedinice" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Prilog" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Nedostaje datoteka" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Nedostaje eksterni link" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Izaberite datoteku za prilog" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Komentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Komentar priloga" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Datum učitavanja" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Datum kada je datoteka učitana" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Veličina datoteke" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Veličina datoteke u bajtovima" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Određen je neispravan tip modela za prilog" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Posebno stanje" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Posebna stanja" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Referentni status podešen" -#: common/models.py:2102 +#: common/models.py:2184 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:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logički ključ" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Vrednost" -#: common/models.py:2114 +#: common/models.py:2196 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:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Ime stanja" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiketa" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Etiketa koja će biti prikazana na korisničkoj strani" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Boja" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Boja koja će biti prikazana na korisničkoj strani" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Model ovog stanja je povezan sa " -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Model mora biti izabran" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Ključ mora biti izabran" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Logički ključ mora biti izabran" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Ključ mora da se razlikuje od logičkog ključa" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Validna referenca statusa klase mora biti dostavljena" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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:2199 +#: common/models.py:2281 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:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Lista odabira" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Liste odabira" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Ime liste odabira" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Opis liste odabira" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Zaključano" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Da li je ova lista odabira zaključana?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Da li se ova lista odabira može koristiti?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Ekstenzija/dodatak za izvor" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Ekstenzija koja pruža listu odabira" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "String izvora" -#: common/models.py:2280 +#: common/models.py:2362 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:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Podrazumevani unos" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Podrazumevani unos za ovu listu odabira" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Kreirano" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Datum i vreme kada je ova lista odabira kreirana" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Poslednje ažuriranje" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Unos liste odabira" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Unosi liste odabira" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Lista odabira kojoj ovaj unos pripada" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Vrednost ovog unosa liste odabira" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Naziv ovog unosa liste odabira" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Opis ovog unosa liste odabira" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Da li je unos ove liste odabira aktivan?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Šablon parametra" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Checkbox parametri ne mogu imati jedinice" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox parametri ne mogu imati izbore" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Izbori moraju biti jedinstveni" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Ime šablona parametra mora biti jedinstveno" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Naziv parametra" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Jedinice" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Fizičke jedinice za ovaj parametar" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Opis parametra" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Polje za potvrdu" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Da li je ovaj parametar checkbox?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Izbori" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "Validni izbori za ovaj parametar (razdvojeni zapetom)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Lista izbora za ovaj parametar" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Omogućen" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Nije validan izbor za vrednost parametra" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Šablon" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Podaci" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Vrednost parametra" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Beleška" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Opciona beleška" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Skeniranje bar koda" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Podaci bar koda" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Korisnik koji je skenirao bar kod" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Vremenski trag" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Datum i vreme skeniranja bar koda" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "URL krajnja tačka kojaj je obradila bar kod" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Kontekst podataka za skeniranje bar koda" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Odgovor" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Podaci odgovora za skeniranje bar koda" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Rezultat" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Da li je skeniranje bar koda bilo uspešno?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Ključ" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Stavke primljene" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Pokrenuto je" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Čekaju se zadaci" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Planirani zadaci" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Propali zadaci" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID zadatka" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Jedinstveni ID zadatka" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Zaključaj" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Vreme zaključavanja" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Naziv zadatka" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funkcija" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Ime funkcije" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argumenti" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Argumenti zadatka" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Ključne reči argumenata" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Ključne reči argumenata zadatka" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Ime datoteke" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Tip modela" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Lista odabira je zaključana" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Nema grupe" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "URL sajta je zaključan od strane konfiguracije" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Ponovno pokretanje potrebno" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Podešavanje je izmenjeno i zahteva ponovno pokretanje servera" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Migracije na čekanju" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Broj migracija baze podataka koje su na čekanju" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Ime instance servera" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Stringovni opis instance servera" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Ime instance korisnika" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Koristi ime instance u naslovnoj liniji" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Zabrani prikazivanje `O nama`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Prikaži `O nama` samo superkorisnicima" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Ime kompanije" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Interno ime kompanije" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Osnovni URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Osnovni URL za instancu servera" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Podrazumevana valuta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Izaberi osnovnu valutu za određivanje cena" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Podržane valute" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Lista kodova podržanih valuta" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Interval ažuriranja valuta" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dani" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Dodatak za ažuriranje valute" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Dodatak za ažuriranje valute koji će se koristiti" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Skini sa URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Dozvoli skidanje sa udaljenih lokacija slika i datoteka" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Ograničenje veličine skidanja" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Maksimalna dozvoljena veličina slike koja se skida" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "Korisnik-agent koji se koristi za skidanje sa URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Dozvoli premošćavanje koji će se korisnik-agent koristiti za skidanje slika i datoteka sa spoljašnjeg URL (ostavi prazno da se podesi kao podrazumevano)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Stroga validacija URL" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "Traži specifikaciju za validaciju URL-ova" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Ažuriraj interval provere" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Koliko često da proveravam za nova ažuriranja? (podesi na nulu da bi isključio)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Automatsko pravljenje rezervne kopije" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Omogući automatsko pravljenje rezervne kopije baze podataka i medijskih datoteka" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Automatski interval pravljenja rezervnih kopija" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Odredi broj dana između automatskih pravljenja rezervnih kopija" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Interval brisanja zadataka" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Rezultati pozadinskih zadataka biće izbrisani nakon određenog broja dana " -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Interval brisanja evidencije grešaka" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Evidencija grešaka biće izbrisana nakon određenog broja dana" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Interval brisanja obaveštenja" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Korisnička obaveštenja biće izbrisana nakon određenog broja dana" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Podrška za bar kod" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Omogući podršku za bar kod skener preko interfejsa stranice" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Uskladišti rezultate bar koda" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Uskladišti rezultate bar koda u bazu podataka" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maksimalan broj skeniranja bar koda" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Maksimalan broj rezultata skeniranja bar koda koji treba da se skladišti" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Kašnjenje unosa bar koda" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Vreme kašnjena obrađivanja ulaza bar koda" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Podrška za bar kod veb kameru" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Omogući skeniranje bar koda pomoću veb kamere u pretraživaču" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Prikaži podatke bar koda" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Prikaži podatke bar koda u pretraživaču kao tekst" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Dodatak za generisanje bar koda" -#: common/setting/system.py:401 +#: common/setting/system.py:394 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:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Revizije dela" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Omogući polje za reviziju dela" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Jedino revizija sastavljanja " -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Dozvoli jedino revizije za sastavne delove" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Dozvoli brisanje iz sastavljanja" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Interni broj dela regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "Regularni obrazac izraza za podudaranje IPN dela" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Dozvoli duple IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "Dozvoli da više delova dele isti IPN" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Dozvoli izmenu IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "Dozvoli izmenu IPN vrednosti u toku izmene dela" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Kopiraj BOM podatke dela" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "Podrazumevaj kopiranje BOM podataka prilikom pravljenja duplikata dela " -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Kopiraj podatke parametara dela" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "Podrazumevaj kopiranje podataka parametara dela prilikom pravljenja duplikata dela" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Kopiraj podatke testiranja dela" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "Podrazumevaj kopiranje podataka testiranja dela prilikom pravljenja duplikata dela" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kopiraj šablone parametara kategorije" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Kopiraj šablone parametara kategorije prilikom pravljenja dela" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Podrazumevano je da su delovi šabloni" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponenta" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Može da se kupi" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Podrazumevano je da se delovi mogu kupiti" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Može da se proda" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "podrazumevano je da delovi mogu da se prodaju" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Podrazumevano je da delovi mogu da se prate" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuelni" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Podrazumevano je da su delovi virtuelni" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Prikaži povezane delove" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Prikaži povezane delove za deo" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Inicijalni podaci zaliha" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "Dozvoli kreiranje inicijalne alihe prilikom dodavanja novog dela" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Podaci inicijalnog dobavljača" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Format prikazivanja imena dela" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Format u kome će se prikazivati ime dela" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Podrazumevana ikona za kategoriju dela" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "Podrazumevana ikona za kategoriju dela (prazno znači bez ikone)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Minimalan broj decimalnih mesta za cene" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Maksimalan broj decimalnih mesta za cene" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Koristi cene dobavljača" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Premosti istorijat kupovina" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Prethodne cene narudžbenice zamenjuje pauze cena dobavljača" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Koristi cene stavki u zalihama" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Godina cena stavki u zalihama" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Koristi drugačije cene" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Uključi drugačije cene u sveukupnim kalkulacijama cene" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Samo aktivne varijante" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "Koristi samo aktivne varijante za određivanje varijante cene" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Vremenski period za ponovno određivanje cena" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interne cene" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Omogući interne cene za delove" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Premošćavanje internih cena" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "Ako su dostupne, interne cene premošćuju kalkulacije opsega cena" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Omogući štampanje etiketa" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Omogući štampanje etiketa preko web interfejsa" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI slike etikete" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Omogući izveštaje" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Omogući generisanje izveštaja" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Mod otklanjanja grešaka" -#: common/setting/system.py:662 +#: common/setting/system.py:663 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:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Greške evidencije izveštaja" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Greške evidentiranja koje se dese prilikom generisanja izveštaja" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Veličina stranice" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Podrazumevana veličina strane za izveštaje u PDF formatu" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Zahtevaj jedinice parametara" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Globalno jedinstveni serijski brojevi" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Obriši ispražnjene zalihe" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Šablon koda serije" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "Šablon za generisanje podrazumevanih kodova serije stavki u zalihama" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Datum isteka zaliha" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Omogući funkcionalnost isteka zaliha" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Prodaja isteklih zaliha" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Dozvoli prodaju isteklih zaliha" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Vreme zastarevanja zaliha" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Izrada sa isteklim zalihama" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Dozvoli izradu sa isteklim zalihama" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Vlasnička kontrola zaliha" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Omogući vlasničku kontrolu nad lokacijama zaliha i stavkama" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Podrazumevana ikonica lokacije zaliha" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "Podrazumevana ikonica lokacije zaliha (prazno znači da nema ikonice)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Prikaži instalirane stavke sa zaliha" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Prikaži instalirane stavke sa zaliha u stok tabelama" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Proveri spisak materijala pri instalaciji stavki" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Dozvoli transfer van zaliha" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Referentni šablon naloga za izradu" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Potreban šablon za generisanje referentnog polja naloga za izradu" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Potreban odgovoran vlasnik" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Odgovoran vlasnik mora biti dodeljen svakom nalogu" -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Potreban aktivan deo" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Spreči kreiranje naloga za izradu za neaktivne delove" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Potreban zaključan deo" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Spreči kreiranje nalogaza izradu za otključane delove" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Potreban validan spisak materijala" -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Potrebno završavanje podređenih naloga" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Blokiraj dok ne prođe test" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Omogući naloge za vraćanje" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "Omogući funkcionalnost vraćana u korisničkom interfejsu" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Referentni šablon naloga za vraćanje" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "Potreban šablon pri generisanju referentnog polja naloga za vraćanje" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Izmeni završene naloge za vraćanje" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Referentni šablon naloga za prodaju" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "Potreban šablon pri generisanju referentnog polja naloga za prodaju" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Podrazumevana isporuka naloga za prodaju" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "Omogućava kreiranje podrazumevane isporuke sa nalozima za prodaju" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Izmeni završene naloge za prodaju" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Označi isporučene naloge kao završene" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 -msgid "Purchase Order Reference Pattern" -msgstr "Referentni šablon naloga za kupovinu" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "Potreban šablon pri generisanju referentnog polja naloga za kupovinu" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "Izmeni završene naloge za kupovinu" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Referentni šablon naloga za kupovinu" + +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" +msgstr "Potreban šablon pri generisanju referentnog polja naloga za kupovinu" + +#: common/setting/system.py:930 +msgid "Edit Completed Purchase Orders" +msgstr "Izmeni završene naloge za kupovinu" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Automatski završi naloge za kupovinu" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Omogući zaboravljenu lozinku" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Omogući funkcionalnost zaboravljene lozinke na stranicama za prijavljivanje" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Omogući registraciju" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "Omogući registraciju korisnicima na stranicama za prijavljivanje" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Omogući SSO" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Omogući SSO na stranicama za prijavljivanje" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Omogući SSO registraciju" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "Omogući SSO sinhronizaciju grupa" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO ključ grupe" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Nazivi grupa dobijaju atribute od IdP-a" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "Mapiranje SSO grupa" -#: common/setting/system.py:966 +#: 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 "Mapiranje SSO grupa u lokalne grupe aplikacije. Ukoliko lokalna grupa ne postoji, biće kreirana." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "Ukloni grupe van SSO" -#: common/setting/system.py:974 +#: 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 "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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Email neophodan" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "Zahtevaj od korisnika da dostavi mejl prilikom registracije" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Automatski popuni SSO korisnike" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "Automatski popuni korisnikove podatke iz SSO naloga" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Email dva puta" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "Pitaj korisnika dva puta za email prilikom registracije" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Lozinka dva puta" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "Pitaj korisnika dva puta za lozinku prilikom registracije" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Dozvoljeni domeni" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Grupa pri registrovanju" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Nametni MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Korisnici moraju koristiti multifaktorsku bezbednost" -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Proveri plugine pri pokretanju" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Proveri ažuriranja pluginova" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "Omogući periodično proveranje pluginova" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Omogući URL integraciju" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "Omogući da pluginovi dodaju URL rute" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Omogući integraciju u navigaciju" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Omogući integraciju pluginova u navigaciju" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Omogući integraciju aplikacija" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Omogući pluginovima da dodaju aplikacije" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Omogući integraciju planiranja" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Omogući da plugini izvršavaju planirane zadatke" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Omogući integraciju događaja" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Omogući da plugini odgovaraju na unutrašnje događaje" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Omogući integraciju interfejsa" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "Omogući integraciju pluginova u korisnički interfejs" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Ne uključuj eksterne lokacije" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Period automatskog popisa" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Prikaži puna imena korisnika" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "Prikaži puna imena korisnika umesto korisničkih imena" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Omogući podatke test stanica" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "Omogući prikupljanje podataka sa test stanica radi rezultata testova" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Primaj izveštaje o greškama" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Primaj notifikacije za sistemske greške" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Poslednje korišćene mašine za štampanje" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Deo je aktivan" msgid "Manufacturer is Active" msgstr "Proizvođač je aktivan" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Deo dobavljača je aktivan" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Interni deo je aktivan" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Dobavljač je aktivan" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Proizvođač" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Kompanija" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Ima zalihe" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Kompanije" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Opis kompanije" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Opis kompanije" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Vebsajt" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Vebsajt kompanije" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Broj telefona" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Broj telefona kontakta" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Email adresa kontakta" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Osoba za kontakt" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Link ka eksternim informacijama o kompaniji" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Da li je ova kompanija aktivna?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Je mušterija" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Da li prodajete stavke ovoj kompaniji?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Je dobavljač" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Da li kupujete stavke od ove kompanije?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Je proizvođač" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Da li ova kompanija proizvodi delove?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Podrazumevana valuta za ovu kompaniju" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adrese" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adrese" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Izaberi kompaniju" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Naslov adrese" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Naslov koji opisuje adresu" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Primarna adresa" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Postavi kao primarnu adresu" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Telefon 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adresa 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Telefon 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adresa 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Poštanski broj" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Grad/region" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Poštanski broj" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Država/provincija" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Država ili provincija" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Zemlja" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adresa zemlje" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Beleške za kurira" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Beleške za kurira" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Interne beleške o isporuci" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Beleške o isporuci za internu upotrebu" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Link za adresne informacije (eksterni)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Deo proizvođača" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Osnovni deo" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Izaberi deo" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Izaberi proizvođača" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "Broj dela proizvođača" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Broj dela proizvođača" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "URL za link eksternog dela proizvođača" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Opis dela proizvođača" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "Jedinice pakovanja moraju biti kompatibilne sa osnovnim jedinicama dela" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Jedinice pakovanja moraju biti veće od nule" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "Povezani delovi dobavljača moraju referencirati isti osnovni deo" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dobavljač" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Izaberi dobavljača" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Jedinica za držanje dobavljačevih zaliha" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Da li je ovaj deo dobavljača aktivan?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Izaberi deo proizvođača" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "URL za link dela eksternog dobavljača" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Opis dela dobavljača" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "osnovni trošak" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimalna naplata (npr. taksa za slaganje)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Pakovanje" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Pakovanje delova" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Količina pakovanja" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "više" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Naruči više" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Količine dostupne od dobavljača" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Dostupnost ažurirana" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Datum poslednjeg ažuriranja podataka o dostupnosti" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Smanjenje cene dobavljača" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Podrazumevana valuta koja se koristi za ovog dobavljača" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Naziv kompanije" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Na zalihama" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Kolona je već mapirana u polje u bazi podataka" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Polje je već mapirano u kolonu sa podacima" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Kolona ne postoji u fajlu sa podacima" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Polje ne postoji u ciljnom modelu" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Izabrano polje je samo za čitanje" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Uvezi sesiju" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Polje" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Kolona" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Indeks vrsta" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Originalni podaci vrste" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Greške" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Važeće" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "Broj kopija za štampanje od svakog natpisa" msgid "Connected" msgstr "Konektovano" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Nepoznato" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupa" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Referenca naloga" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Izvanredno" @@ -4728,7 +4828,7 @@ msgstr "Izvanredno" msgid "Has Project Code" msgstr "Ima šifru projekta" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Kreirano do strane" @@ -4764,57 +4864,69 @@ msgstr "Krajnji datum pre" msgid "Target Date After" msgstr "Krajnji datum nakon" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Ima cenu" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Završen pre" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Završen nakon" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Nalog" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Nalog završen" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Interni deo" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Nalog na čekanju" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Završeno" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Ima isporuku" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Nalog za kupovinu" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Nalog za kupovinu" msgid "Sales Order" msgstr "Nalog za prodaju" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Ukupna cena" msgid "Total price for this order" msgstr "Totalna cena ovog naloga" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Valuta naloga" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta za ovaj nalog (ostaviti prazno za podrazumevanu valutu kompanije)" @@ -4851,718 +4963,750 @@ msgstr "Valuta za ovaj nalog (ostaviti prazno za podrazumevanu valutu kompanije) msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "Kontakt se ne poklapa sa izabranom kompanijom" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Opis naloga (opciono)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Izaberi šifru projekta za ovaj nalog" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Link ka eksternoj stranici" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Ciljani datum" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Datum izdavanja" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Datum kada je nalog izdat" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Korisnik ili grupa odgovorni za ovaj nalog" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Lice za kontakt za ovaj nalog" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Adresa kompanije za ovaj nalog" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Referenca naloga" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Status naloga za kupovinu" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Kompanija od koje su stavke naručene" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Referenca dobavljača" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Referentni kod dobavljača naloga" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "primljeno od strane" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Datum kada je nalog završen" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Odredište" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Odredište za primljene stavke" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Dobavljač dela se mora poklapati sa dobavljačem naloga za kupovinu" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Stavka porudžbine se ne poklapa sa nalogom za kupovinu" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Količina mora biti pozitivan broj" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Mušterija" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Kompanija kojoj se prodaju stavke" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Status naloga za prodaju" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Referenca mušterije" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Referentni kod mušterijinog naloga" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Datum isporuke" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "isporučeno od strane" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Nalog je već završen" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Nalog je već otkazan" -#: order/models.py:1423 +#: order/models.py:1463 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:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 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:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Količina stavki" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Referenca stavke porudbžine" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Beleške stavke porudbžine" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Opis stavke porudžbine (opciono)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Dodatni kontekst za ovu porudžbinu" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Cena jedinice" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Stavka porudžbine naloga za kupovinu" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Deo dobavljača se mora poklapati sa dobavljačem" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Deo dobavljača" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Primljeno" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Broj primljenih stavki" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Kupovna cena" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Kupovna cena jedinice" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Dodatna porudbžina naloga za kupovinu" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Stavka porudžbine naloga za prodaju" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Prodajna cena" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Prodajna cena jedinice" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Poslato" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Isporučena količina" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Isporuka naloga za prodaju" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Datum isporuke" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Datum dostavljanja" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Datum dostavljanja isporuke" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Provereno od strane" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Korisnik koji je proverio ovu isporuku" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Isporuka" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Broj isporuke" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Broj praćenja" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Informacije o praćenju isporuke" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Broj računa" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Referentni broj za dodeljeni račun" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Isporuka je već poslata" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Isporuka nema alocirane stavke sa zaliha" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Dodatne porudbžine naloga za prodaju" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Alokacije naloga za prodaju" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Stavka sa zaliha nije dodeljena" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Ne mogu se alocirati zalihe porudbžini bez dela" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Alocirana količina ne sme da pređe količinu zaliha" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Količina alokacije mora da bude veća od nule" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Količina mora biti 1 za serijalizovane stavke sa zaliha" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Nalog za prodaju se ne poklapa sa isporukom" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Isporuka se ne poklapa sa nalogom za prodaju" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Porudbžina" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Referenca isporuke naloga za prodaju" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Stavka" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Izaberi stavku sa zaliha za alokaciju" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Unesi količinu za alokaciju zaliha" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Referenca naloga za vraćanje" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Kompanija čije stavke su vraćene" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Status naloga za vraćanje" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "Vrati stavku porudbžine" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Stavka sa zaliha mora biti određena" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "Količina vraćanja je premašila količinu zaliha" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "Količina vraćanja mora biti veća od nule" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Nevažeća količina za serijalizovane stavke sa zaliha" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Izaberi stavku za vraćanje od mušterije" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Primljeno datuma" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Ishod" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Ishod za ovu stavku porudžbine" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Doda" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "ID naloga" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "ID naloga koji će se duplirati" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Kopiraj porudžbine" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Kopiraj stavke porudžbine sa originalnog naloga" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Kopiraj dodatne porudžbine" -#: order/serializers.py:95 +#: 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:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Stavke porudbžine" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Završene porudbžine" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Dupliraj nalog" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "Odredi opcije za dupliranje ovog naloga" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Nevažeći ID naloga" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Naziv dobavljača" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Nalog ne može biti otkazan" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "Dozvoli da nalog bude zatvoren sa nepotpunim porudžbinama" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Nalog ima nepotpune stavke porudžbine" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Nalog nije otvoren" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Automatske cene" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Valuta kupovne cene" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Spoj stavke" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "Jedinica za praćenje zaliha" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Interni broj dela" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Interni naziv dela" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Deo dobavljača mora biti određen" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Nalog za kupovinu mora biti određen" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Dobavljač mora da se poklapa sa nalogom za kupovinu" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Nalog za kupovinu mora da se poklapa sa dobavljačem" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Stavka porudbžine" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Izaberi odredišnu lokaciju za primljene stavke" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Unesi šifru ture za nadolazeće stavke sa zaliha" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Datum isteka" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Unesi serijske brojeve za nadolazeće stavke sa zaliha" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Promeni informacije o pakovanju za nadolazeće stavke sa zaliha" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Dodatne beleške za nadolazeće stavke sa zaliha" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Bar kod" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Skeniran bar kod" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Bar kod je već u upotrebi" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Stavke porudžbine moraju biti dostavljene" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Odredišna lokacija mora biti određena" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Pružene vrednosti bar kodova moraju biti jedinstvene" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Isporuke" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Završene isporuke" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Valuta prodajne cene" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Alocirane stavke" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Nisu dostavljeni detalji isporuke" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Količina mora biti pozitivna" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Unesi serijske brojeve za alokaciju" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Isporuka je već isporučena" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Isporuka nije povezana sa ovim nalogom" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Sledeći serijski brojevi su nedostupni" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Stavka porudžbine naloga za vraćanje" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Stavka porudžbine se ne poklapa sa nalogom za vraćanje" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Stavka porudžbine je već primljena" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "Količina za vraćanje" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Valuta cene porudžbine" @@ -5598,146 +5742,150 @@ msgstr "Refundiraj" msgid "Reject" msgstr "Odbij" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Istekli nalozi za kupovinu" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Nalog za kupovinu {po} je sada istekao" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Istekli nalozi za prodaju" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Nalog za prodaju {so} je sada istekao" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Označeno zvezdicom" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Filtiraj po kategorijama označenim zvezdicom" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Dubina" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Filtriraj po dubini kategorije" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Vrhovni" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Filtriraj po vrhovnim kategorijama" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Kaskadno" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Uključi pod-kategorije u filtriranim rezultatima" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Nadređen" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Filtriraj po nadređenoj kategoriji" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Ne uključuj pod-kategorije pod specifičnom kategorijom" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Ima rezultate" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Je revizija" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Ima revizije" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "Spisak materijala validan" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Deo sklopa se može testirati" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Deo komponente se može testirati" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Koristi" @@ -5746,11 +5894,11 @@ msgstr "Koristi" msgid "Part Category" msgstr "Kategorija dela" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Kategorije delova" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Podrazumevana lokacija" @@ -5778,7 +5926,7 @@ msgstr "Podrazumevane ključne reči za delove ove kategorije" msgid "Icon" msgstr "Ikonica" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikonica (opciono)" @@ -5799,1025 +5947,1050 @@ msgstr "Podrazumevana vrednost" msgid "Default Parameter Value" msgstr "Podrazumevana vrednost parametra" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Delovi" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Ovaj deo se ne može izbrisati jer je zaključan" -#: part/models.py:593 +#: part/models.py:594 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:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "Interni broj dela se mora slagati sa regex šablonom {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Deo ne može biti revizija samog sebe" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Ne može se kreirati revizija dela koji je već revizija" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Šifra revizije mora biti dostavljena" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Revizije su dozvoljene samo za delove sklopove" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Ne može se izvršiti revizija šablonskog dela" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Nadređeni deo mora biti vezan sa istim šablonom" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Stavka sa ovim serijskim brojem već postoji" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplirani interni brojevi dela nisu dozvoljeni u podešavanjima dela" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Identična revizija dela već postoji" -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Delovi ne mogu biti dodeljeni strukturnim kategorijama delova!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Naziv dela" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Jeste šablon" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Da li je ovaj deo šablonski deo?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Da li je ovaj deo varijanta drugog dela?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Varijanta od" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Opis dela (opciono)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Ključne reči" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Kategorija dela" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Interni broj dela" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Revizija dela ili broj verzije" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revizija" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Da li je ovaj deo revizija drugog dela?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Revizija od" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Gde je ova stavka inače skladištena?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Podrazumevani istek" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimalne zalihe" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Minimalni dozvoljen nivo zaliha" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Jedinice mere za ovaj deo" -#: part/models.py:1254 +#: part/models.py:1258 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:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Da li ovaj deo ima praćenje za više stavki?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Da li ovaj deo može imati svoje rezultate testa?" -#: part/models.py:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Da li ovaj deo može biti prodat mušterijama?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Da li je ovaj deo aktivan?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Zaključani delovi se ne mogu menjati" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Suma spiska materijala" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Uskladištena suma spiska materijala" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "Spisak materijala proveren od strane" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Spisak materijala proveren datuma" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Korisnik koji je kreirao" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Vlasnik odgovoran za ovaj deo" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Prodaj više" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Valuta korišćena za vršenje proračuna o cenama" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimalna vrednost spiska materijala" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Minimalna vrednost komponenti delova" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maksimalna vrednost spiska materijala" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Maksimalna vrednost komponenti delova" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimalna kupovna vrednost" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimalna istorijska kupovna vrednost" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maksimalna kupovna vrednost" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maksimalna istorijska kupovna vrednost" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimalna interna cena" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Minimalna cena bazirana na internim sniženjima cena" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maksimalna interna cena" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Maksimalna vrednost bazirana na internim sniženjima cena" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimalna cena dobavljača" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Minimalna cena dela od eksternih dobavljača" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maksimalna cena dobavljača" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Maksimalna cena dela od eksternih dobavljača" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimalna vrednost varijanti" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Izračunata minimalna vrednost varijanti delova" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maksimalna vrednost varijanti" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Izračunata maksimalna vrednost varijanti delova" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimalna vrednost" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Promeni minimalnu vrednost" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maksimalna vrednost" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Promeni maksimalnu vrednost" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Ukupna izračunata minimalna vrednost" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Ukupna izračunata maksimalna vrednost" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimalna prodajna cena" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Minimalna prodajna cena bazirana na osnovu sniženja cena" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maksimalna prodajna cena" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Maksimalna prodajna cena bazirana na osnovu sniženja cena" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimalna prodajna vrednost" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimalna istorijska prodajna cena" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maksimalna prodajna vrednost" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maksimalna istorijska prodajna cena" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Deo za popis" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Broj stavki" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Broj individualnih unosa zaliha u vreme popisa" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Ukupne dostupne zalihe za vreme popisa" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Datum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Datum kada je izvršen popis" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimalna vrednost zaliha" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Procenjena minimalna vrednost trenutnih zaliha" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maksimalna vrednost zaliha" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Procenjena maksimalna vrednost trenutnih zaliha" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Smanjenje prodajne cene dela" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Šablon testa dela" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Naziv testa" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Unesi naziv za ovaj test" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Test ključ" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Pojednostavljen ključ za test" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Opis testa" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Unesi opis za ovaj test" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Da li je ovaj test omogućen?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Neophodno" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Da li je neophodno da ovaj test prođe?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Zahteva vrednost" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Zahteva prilog" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "Validni izbori za ovaj test (razdvojeni zapetom)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 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:3961 +#: part/models.py:4030 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:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Izaberi nadređeni deo" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Pod-deo" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Izaberi deo koji će biti korišćen u spisku materijala" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Količina spiskova materijala za ovu stavku sa spiska materijala" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Ova stavka sa spiska materijala je opciona" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Referenca stavke sa spiska materijala" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Beleške stavki sa spiska materijala" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Suma" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Suma spiska materijala" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validirano" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Ova stavka sa spiska materijala je validirana" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Biva nasleđeno" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 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:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Zamenski deo mora biti određen" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Zamenska stavka sa spiska materijala" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Nadređena stavka sa spiska materijala" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Zamenski deo" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Deo 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Deo 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Izaberi povezan deo" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Beleška za ovu relaciju" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Identična veza već postoji" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Nadređena kategorija" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Nadređena kategorija dela" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Podkategorije" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Rezultati" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Broj rezultata napravljenih na osnovu ovog šablona" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Valuta kupovine za ovu stavku sa zaliha" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Originalni deo" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Izaberi originalni deo za duplikaciju" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopiraj sliku" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Kopiraj sliku sa originalnog dela" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Kopiraj spisak materijala" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "Kopiraj spisak materijala sa originalnog dela" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Kopiraj parametre" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Kopiraj parametarske podatke sa originalnog dela" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Kopiraj beleške" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Kopiraj beleške sa originalnog dela" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Inicijalna količina zaliha" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Inicijalna lokacija zaliha" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Odredi inicijalnu lokaciju zaliha za ovaj deo" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Izaberi dobavljača (ostavi prazno za preskakanje)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Izaberi proizvođača (ostavi prazno za preskakanje)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Broj dela proizvođača" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Izabrana kompanija nije validan dobavljač" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Izabrana kompanija nije validan proizvođač" -#: part/serializers.py:516 +#: part/serializers.py:527 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:523 +#: part/serializers.py:534 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:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Naziv kategorije" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Izrađivanje" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Stavke sa zaliha" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revizije" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Ukupne zalihe" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Nealocirane zalihe" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Varijante zaliha" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Dupliraj deo" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Kopiraj inicijalne podatke od drugog dela" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Početne zalihe" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Kreiraj deo sa početnom količinom zaliha" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Informacije o dobavljaču" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Dodaj inicijalne informacije o dobavljaču za ovaj deo" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kopiraj parametre kategorije" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Kopiraj parametarske šablone sa izabrane kategorije dela" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Postojeća slika" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Ime fajla postojeće slike dela" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Fajl sa slikom ne postoji" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Validiraj ceo spisak materijala" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Može se izgraditi" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimalna cena" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Izmeni izračunatu vrednost za minimalnu cenu" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Minimalna valuta cene" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maksimalna cena" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Izmeni izračunatu vrednost maksimalne cene" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Maksimalna valuta cene" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Ažuriraj" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Ažuriraj cene za ovaj deo" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Minimalna cena ne sme biti veća od maksimalne cene" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Maksimalna cena ne sme biti manja od minimalne cene" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Izaberi nadređeni sklop" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Izaberi komponentu dela" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "Izaberi deo sa kog će se kopirati spisak materijala" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Ukloni postojeće podatke" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Ukloni postojeće stavke sa spiska materijala pre kopiranja" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Uključi nasleđeno" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Preskoči nevažeće vrste" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "Omogući ovu opciju za preskakanje nevažećih vrsta" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Kopiraj zamenske delove" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopiraj zamenske delove prilikom duplikacije stavki sa spiska materijala" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Notifikacija o niskim zalihama" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Količina za alociranje" msgid "Label printing failed" msgstr "Greška pri štampanju natpisa" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Greška pri renderovanju natpisa u PDF" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Greška pri renderovanju natpisa u HTML" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Nijedna stavka nije poslata na štampu" @@ -7100,7 +7273,7 @@ msgstr "Pruža ugrađenu podršku za bar kodove" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "PDF štampanje natpisa" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "Pruža podršku za štampanje PDF natpisa" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Debug mod" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Omogućava debug mod - vraća sirov HTML umesto PDF-a" @@ -7500,7 +7673,7 @@ msgstr "Border" msgid "Print a border around each label" msgstr "Štampa border oko svakog natpisa" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Lendskejp" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Samo osoblje može da administrira pluginove" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Instalacija plugina je onemogućena" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Plugin instaliran uspešno" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Instaliran plugin na {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Plugin nije pronađen u registru" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Plugin nije paket plugin" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Ime paketa plugina nije pronađeno" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Samo osoblje može da administrira pluginove" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Deinstaliranje plugina je onemogućeno" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin ne može biti deinstaliran jer je trenutno aktivan" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Plugin nije instaliran" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Instalacija plugina nije pronađena" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Plugin uspešno deinstaliran" @@ -7689,21 +7875,21 @@ msgstr "Paket plugin" msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Nije pronađen autor" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin zahteva najmanje verziju {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin zahteva najviše verziju {v}" @@ -7884,55 +8070,55 @@ msgstr "Instalacija nije potvrđena" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Potpuno ponovno učitavanje" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Izvrši potpuno ponovno učitavanje registra pluginova" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Nasilno ponovo učitaj" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Nasilno ponovo učitaj registar pluginova, iako je već učitan" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Skupi plugine" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Skupi plugine i dodaj ih u registar" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Aktiviraj plugin" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Aktiviraj ovaj plugin" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Obriši konfiguraciju" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Obriši konfiguraciju plugina iz baze podataka" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Stavke" @@ -7948,7 +8134,7 @@ msgstr "Plugin ne podržava štampanje natpisa" msgid "Invalid label dimensions" msgstr "Nevažeće dimenzije natpisa" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Nema važećih stavki dostavljenih šablonu" @@ -7972,152 +8158,156 @@ msgstr "Letter" msgid "Template file with this name already exists" msgstr "Šablonski fajl sa ovim imenom već postoji" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Ime šablona" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Opis šablona" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Broj revizija (auto-inkrement)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Priloži kao model uz štampanje" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Šablon imena fajlova" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Šablon za generisanje imena fajlova" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Šablon je omogućen" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Tip ciljanog modela za šablon" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filteri" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Šablonski fajl" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Veličina strane za PDF izveštaje" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Renderuj izveštaj u landscape orijentaciji" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Širina (u milimetrima)" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Širina natpisa, u milimetrima" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Visina (u milimetrima)" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Visina natpisa, u milimetrima" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Isečak" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Izveštaj isečka fajla" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Opis isečka fajla" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Sredstvo" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Izveštaj fajla sredstva" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Opis fajla sredstva" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Izaberi šablon izveštaja" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 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:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Izaberi šablon natpisa" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Plugin za štampanje" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Izaberi plugin za korišćenje prilikom štampanja natpisa" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serijski broj" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Instalirane stavke" @@ -8248,184 +8438,196 @@ msgstr "Nema rezultata (neophodno)" msgid "No result" msgstr "Nema rezultata" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Fajl ne postoji" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Slika nije pronađena" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image tag zahteva instancu dela" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image tag zahteva instancu kompanije" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Filtriraj po dubini lokacije" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Filtriraj po nadređenim lokacijama" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Uključi podlokacije u filtriranim rezultatima" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Nadređena lokacija" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Filtriraj po nadređenoj lokaciji" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Ime dela" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "Ime dela sadrži" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Ime dela (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Interni deo broja" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "Interni deo broja sadrži (osetljivo na velika i mala slova)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Interni broj dela (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Minimalne zalihe" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Maksimalne zalihe" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Statusni kod" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Eksterna lokacija" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Potrošeno od strane naloga za izradu" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "Instalirano u drugu stavku sa zaliha" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Stablo dela" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "Ažurirano pre" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Ažurirano nakon" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "Popis pre" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "Popis nakon" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Datum isteka pre" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Datum isteka nakon" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Zastarelo" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Količina je neophodna" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Validan deo mora biti dosavljen" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "Dati dobavljač ne postoji" -#: stock/api.py:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Tipovi lokacija zaliha" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Lokacija zaliha" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Lokacija zaliha" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Vlasnik" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Izaberi vlasnika" @@ -8461,7 +8663,7 @@ msgstr "Izaberi vlasnika" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Eksterna" @@ -8481,274 +8683,282 @@ msgstr "Tip lokacija zaliha za ovu lokaciju" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Deo mora biti određen" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Stavka sa zaliha ne može biti kreirana za virtuelne delove" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Stavka ne može da pripada samoj sebi" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Referenca izgradnje ne ukazuje na isti objekat dela" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Nadređena stavka sa zaliha" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Osnovni deo" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Gde je locirana ova stavka sa zaliha?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Pakovanje u kom je ova stavka sa zaliha" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Instalirano u" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Da li je ova stavka instalirana u drugu stavku?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Serijski broj za ovu stavku" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Šifra ture za ovu stavku sa zaliha" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Količina zaliha" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Izvorna gradnja" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Nalog za ovu stavku sa zaliha" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Potrošeno od strane" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "Nalog za izradu koji je potrošio ovu stavku sa zaliha" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Izvorni nalog za kupovinu" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Nalog za kupovinu za ovu stavku sa zaliha" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Odredište naloga za prodaju" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Obriši kad je potrošeno" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "Obriši ovu stavku sa zaliha kada su zalihe potrošene" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "Cena kupovine jedne jedinice u vreme kupovine" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Konvertovano u deo" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "Deo nije postavljen kao deo koji je moguće pratiti" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Količina mora biti ceo broj" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "Serijski brojevi moraju biti dostavljeni kao lista" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Količine se ne poklapaju sa serijskim brojevima" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "Test šablon ne postoji" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "Stavka sa zaliha je dodeljena nalogu za prodaju" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "Stavka sa zaliha je instalirana u drugu stavku" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Stavka sa zaliha sadrži druge stavke" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "Stavka sa zaliha je dodeljena mušteriji" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Stavka sa zaliha je trenutno u produkciji" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Serijalizovane zalihe se ne mogu spojiti" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Dupliraj stavke sa zaliha" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "Stavke sa zaliha se moraju odnositi na isti deo" -#: stock/models.py:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Statusne šifre zaliha moraju da se poklapaju" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "Praćenje stavke sa zaliha" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Ulazne beleške" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "Rezultat testa stavke sa zaliha" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "Vrednost mora biti dostavljena za ovaj test" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "Prilog mora biti dostavljen za ovaj test" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "Nevažeća vrednost za ovaj test" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Rezultat testa" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Vrednost završetka testa" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Prilog uz test rezultat" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Beleške sa testa" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "Stanica za testiranje" -#: stock/models.py:3085 +#: stock/models.py:3111 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:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Započeto" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "Vreme početka testa" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "Završeno" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "Vreme završetka testa" @@ -8792,246 +9002,246 @@ msgstr "Izaberi deo za koji će se generisati serijski broj" msgid "Quantity of serial numbers to generate" msgstr "Količina serijskih brojeva koji će se generisati" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "Test šablon za ovaj rezultat" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "ID šablona ili ime testa mora biti dostavljeno" -#: stock/serializers.py:294 +#: stock/serializers.py:303 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:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Nadređena stavka" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "Nadređena stavka sa zaliha" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Unesi serijske brojeve za nove stavke" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Dobavljački broj dela" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Isteklo" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Podređene stavke" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "Stavke za praćenje" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "Nabavna cena ove stavke, po jedinici ili pakovanju" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "Unesi broj stavka sa zaliha za serijalizaciju" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Odredišna lokacija zaliha" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "Serijski brojevi ne mogu biti dodeljeni ovom delu" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Serijski broj već postoji" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Izaberi stavku za instaliranje" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Količina za instaliranje" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Izaberi količinu stavki za instaliranje" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Dodaj beleške transakcija (opciono)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "Količina za instaliranje mora biti najmanje 1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Stavka je nedostupna" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "Izabrani deo nije na spisku materijala" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "Količina za instaliranje ne sme preći dostupnu količinu" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Odredišna lokacija za deinstalirane stavke" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "Izaberi deo u koji će se konvertovati stavka" -#: stock/serializers.py:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Statusni kod stavke sa zaliha" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Izaberi stavke kojoj će se promeniti status" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Nije izabrana stavka" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Podlokacije" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "Lokacija nadređenih zaliha" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Deo mora biti za prodaju" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "Stavka je alocirana nalogu za prodaju" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "Stavka je alocirana nalogu za izradu" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "Mušterija kojoj će se dodeliti stavke sa zaliha" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "Izabrana kompanija nije mušterija" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Beleške dodeljivanja zaliha" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "Lista stavki mora biti dostavljena" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Beleške spajanja zaliha" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Dozvoli neslagajuće dobavljače" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "Dozvoli spajanje stavki sa različitim delovima dobavljača" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Dozvoli neslagajući status" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "Dozvoli spajanje stavki sa različitim statusnim kodovima" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "Bar dve stavke moraju biti dostavljene" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Nema promena" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Vrednost primarnog ključa stavke" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "Stavka nije na zalihama" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Beleške transakcija zaliha" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Poslednji put kada je token korišćen" msgid "Revoked" msgstr "Opozvano" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Skup dozvola" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Pregledaj" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Dozvola za pregled stavki" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Dodaj" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Dozvola za dodavanje stavki" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Promeni" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Dozvole za izmenu stavki" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Obriši" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Dozvola za brisanje stavki" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Nalozi za kupovinu" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Nalozi za prodaju" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Nalozi za vraćanje" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Korisničko ime" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Ime" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Ime korisnika" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Prezime" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Prezime korisnika" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Adresa E-pošte korisnika" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Osoblje" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Da li ovaj korisnik ima dozvole koje ima osoblje?" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Super korisnik" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Da li je ovaj korisnik Super korisnik?" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Da li je nalog ovog korisnika aktivan?" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Vaš nalog je kreiran" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Molimo vas koristite opciju resetovanja lozinke da biste se prijavili" -#: users/serializers.py:452 +#: users/serializers.py:497 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 a310c49a42..5366e73e04 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API-slutpunkt hittades inte" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Användaren har inte behörighet att se denna modell" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Ogiltigt antal angivet" @@ -112,13 +105,13 @@ msgstr "Ange datum" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Anteckningar" @@ -131,75 +124,91 @@ msgstr "Värdet '{name}' visas inte i mönsterformat" msgid "Provided value does not match required pattern: " msgstr "Det angivna värdet matchar inte det obligatoriska mönstret: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Tom serienummersträng" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Serienummret finns redan" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ogiltig grupp: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Gruppintervall {group} överstiger tillåtet antal ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Inga serienummer hittades" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Ta bort HTML-taggar från detta värde" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Anslutningsfel" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Servern svarade med ogiltig statuskod" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Undantag inträffade" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Servern svarade med ogiltigt innehållslängdsvärde" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Bilden är för stor" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Nedladdning av bilder överskred maximal storlek" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Fjärrservern returnerade tomt svar" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Angiven URL är inte en giltig bildfil" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-postadress" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Referensen måste matcha obligatoriskt mönster" msgid "Reference number is too large" msgstr "Referensnumret är för stort" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Ogiltigt val" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Namn" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Beskrivning" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Beskrivning (valfritt)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Sökväg" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown anteckningar (valfritt)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Streckkodsdata" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Tredje parts streckkodsdata" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Streckkodsdata" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Unik hash med streckkodsdata" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Befintlig streckkod hittades" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Serverfel" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Ett fel har loggats av servern." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Måste vara ett giltigt nummer" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Välj valuta från tillgängliga alternativ" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Ogiltigt värde" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Fjärransluten bild" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL för fjärrbildsfil" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Nedladdning av bilder från fjärr-URL är inte aktiverad" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Kinesiska (Förenklad)" msgid "Chinese (Traditional)" msgstr "Kinesiska (Traditionell)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Ogiltig fysisk enhet" msgid "Not a valid currency code" msgstr "Inte en giltig valutakod" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Orderstatus" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Föregående tillverkning" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Inkludera varianter" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Inkludera varianter" msgid "Part" msgstr "Del" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategori" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Tilldelad till" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Skapad före" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Skapad efter" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Har startdatum" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Tillverkningen måste avbrytas innan den kan tas bort" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Valfri" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Spårad" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Testbar" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Allokerad" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Konsumerad" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Byggorder" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Plats" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Byggordrar" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Tillverknings order referens" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Tillverknings order referens" msgid "Reference" msgstr "Referens" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Välj del att tillverka" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Försäljningsorderreferens" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Källa Plats" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Destinationsplats" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Tillverkat antal" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Antal lagerobjekt att bygga" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Slutförda objekt" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Antal lagerposter som har slutförts" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Tillverknings status" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Tillverkning statuskod" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Batchkod" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Batch-kod för denna byggutdata" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Skapad" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Datum för slutförande" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Slutförandedatum" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "slutfört av" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Utfärdad av" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Användare som utfärdade denna tillverknings order" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarig" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Extern länk" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Länk till extern URL" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Projektkod" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "Tillverknings order {build} har slutförts" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "En tillverknings order har slutförts" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Ingen byggutgång angiven" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Byggutgång är redan slutförd" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Byggutgång matchar inte bygg order" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Bygg objekt" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antal" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Antal måste vara 1 för serialiserat lager" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Lagerposten är överallokerad" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Artikel i lager" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Källa lagervara" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Lagersaldo att allokera för att bygga" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Installera till" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Destination lagervara" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Delnamn" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Bygg utdata" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Byggutdata matchar inte överordnad version" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Ange serienummer för att tillverkade produkter" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "En lista över tillverkade produkter måste anges" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Lagerplats för skrotade produkter" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "Ignorera alla lagerallokeringar för skrotade produkter" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Plats för färdiga produkter" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Slutför utfall om lager inte har tilldelats fullt ut" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Ta bort ofullständiga produkter" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Ta bort eventuella produkter som inte har slutförts" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Acceptera ofullständig" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Tillverknings ordern är ofullständig" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Spårbar" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Ärvd" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Tillåt varianter" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "Avbruten" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Slutför" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Är länk" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Är fil" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Uppdaterad" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Uppdaterad av" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Unik projektkod" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Projektbeskrivning" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Användare" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Pris" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktiv" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Hemlig" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Meddelande-ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Värd" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Id" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Titel" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Länk" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Sammanfattning" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Läs" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Bildfil" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Definition" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Bilaga" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Saknad fil" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Extern länk saknas" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Modelltyp" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Välj fil att bifoga" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Uppladdningsdatum" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Filstorlek" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logisk nyckel" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Värde" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etikett" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Färg" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Modell" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Låst" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Källsträng" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Skapad" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Senast uppdaterad" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parametermall" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Kryssruta" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Val" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Aktiverad" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Mall" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Data" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Streckkodsdata" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Tidsstämpel" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Sammanhang" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Svar" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Resultat" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Ett fel inträffade" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "E-postmeddelande" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Bekräftad" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Inget svar" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "Tråd-ID" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Tråd" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "E-posttrådar" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Nyckel" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Väntande uppgifter" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Schemalagda uppgifter" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Misslyckade uppgifter" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Uppgifts-ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Lås" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Uppgiftsnamn" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Funktion" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Funktionsnamn" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argument" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Filnamn" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Modelltyp" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Ingen grupp" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Omstart krävs" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Serverinstans (Namn)" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Företagsnamn" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Internt företagsnamn" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Bas-URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Bas-URL för serverinstans" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Standardvaluta" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "dagar" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "Ladda ner från URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Tillåt nedladdning av bilder och filer från extern URL" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Stöd för streckkoder" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Virtuell" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Delar är virtuella som standard" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Visa relaterade delar" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Visa relaterade delar för en del" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Visningsformat för delnamn" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Formatera för att visa artikelnamnet" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Interna priser" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Aktivera etikettutskrift" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Aktivera etikettutskrift från webbgränssnittet" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Etikettbild DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Aktivera rapporter" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Aktivera generering av rapporter" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Debugläge" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: 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:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "Standard sidstorlek för PDF-rapporter" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" -msgstr "Aktivera registrering" - -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" -msgstr "Aktivera SSO" - -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: 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 "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +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:964 -msgid "SSO group map" -msgstr "" +#: common/setting/system.py:965 +msgid "Enable SSO" +msgstr "Aktivera SSO" #: common/setting/system.py:966 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" -msgstr "Tillåtna domäner" - -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: 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 "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1014 -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:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1015 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" -msgstr "" +msgid "Allowed domains" +msgstr "Tillåtna domäner" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Tillverkare" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Företag" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Företag" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Företagsbeskrivning" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Webbplats" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefonnummer" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Kontakt" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Är kund" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Är leverantör" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Är tillverkare" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adress" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adresser" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Välj företag" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Primär adress" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Rad 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Adressrad 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Rad 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Adressrad 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Postnummer" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Land" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Basdel" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Välj del" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "MPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverantör" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Välj leverantör" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Företagsnamn" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "I lager" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Fält" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Kolumn" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Radindex" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Fel" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Giltig" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "Ansluten" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Okänd" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grupp" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "Har projektkod" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Skapad av" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Intern del" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Slutförd" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "Försäljningsorder" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Startdatum" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Måldatum" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Status" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Mål" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kund" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Skickad" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Leveransdatum" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Kontrollerad av" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Fakturanummer" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Allokeringsmängden måste vara större än noll" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Rad" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Leverantörsnamn" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Streckkod" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "Återbetala" msgid "Reject" msgstr "Avvisa" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Djup" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Har resultat" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Är variant" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Använder" @@ -5746,11 +5894,11 @@ msgstr "Använder" msgid "Part Category" msgstr "Delkategori" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Ikon (valfritt)" @@ -5799,1025 +5947,1050 @@ msgstr "Standardvärde" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Artiklar" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Delnamn" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Är mall" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Variant av" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Nyckelord" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Delkategori" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revision" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Datum" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Validerad" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Del 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Del 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Underkategorier" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Resultat" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Originaldel" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Kopiera bild" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "Kopiera parametrar" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Kopiera test" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategorinamn" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revisioner" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Uppdatera" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Hoppa över ogiltiga rader" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Mallnamn" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filter" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Mallfil" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Bredd [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Höjd [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "Inga resultat" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Statuskod" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Extern plats" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "Uppdaterad efter" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Ägare" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Välj ägare" @@ -8461,7 +8663,7 @@ msgstr "Välj ägare" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Grunddel" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Konverterad till del" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Testresultat" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "Startad" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "Ingen förändring" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Visa" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Lägg till" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Ändra" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Radera" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "Gäst" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "Språk" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "Tema" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "Visningsnamn" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "Användartyp" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "Organisation" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "Primär grupp" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Användarnamn" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Förnamn" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Förnamn på användaren" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Efternamn" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Efternamn på användaren" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Avsändarens E-postadress" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personal" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Har den här användaren behörighet för personal" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superanvändare" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Är den här användaren en superanvändare" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Är detta användarkonto aktivt" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "Lösenord" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Ditt konto har skapats." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 91802275ff..6fc7cd6b1f 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Thai\n" "Language: th_TH\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "ไม่พบ API endpoint" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "ปริมาณสินค้าไม่ถูกต้อง" @@ -112,13 +105,13 @@ msgstr "ป้อนวันที่" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "หมายเหตุ" @@ -131,75 +124,91 @@ msgstr "" msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "หมายเลขซีเรียลซ้ำกัน" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "ไม่พบหมายเลขซีเรียล" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "การเชื่อมต่อขัดข้อง" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "ไฟล์รูปภาพมีขนาดใหญ่เกินไป" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "อีเมล" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "ชื่อ" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "คำอธิบาย" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "ข้อมูลบาร์โค้ด" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "บาร์โค้ดนี้มีในระบบแล้ว" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "เกิดข้อผิดพลาดที่เซิร์ฟเวอร์" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "ต้องเป็นตัวเลข" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "สกุลเงิน" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "สถานที่" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "ออกโดย" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "จำนวนต้องมีค่ามากกว่า 0" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "ยกเลิกแล้ว" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "สำเร็จแล้ว" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "ผู้ใช้งาน" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "ลิงก์" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "ไฟล์แนบ" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "ไม่พบไฟล์" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "เลือกไฟล์ที่ต้องการแนบ" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "ความคิดเห็น" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "ชื่อไฟล์" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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 "" -#: common/setting/system.py:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1009 +msgid "Email required" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1014 -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:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "สำเร็จแล้ว" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "สถานะ" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "จัดส่งแล้ว" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "ชิ้นส่วน" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "" -#: users/serializers.py:309 -msgid "Staff" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 276ea03d2b..ac6a778ad0 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API uç noktası bulunamadı" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Toplu işlem için öge veya filtre listesi sağlanmalıdır" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Ögeler bir liste olarak sağlanmalıdır" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Geçersiz ögeler listesi sağlandı" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Filtreler bir sözlük olarak sağlanmalıdır" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Geçersiz filtreler sağlandı" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "Tüm filtre yalnızca true ile kullanılmalıdır" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Sağlanan ölçüte uygun bir eşleşme yok" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Değer verilmemiş" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "Bu alan eşsiz olmalı." -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "Kullanıcının bu modeli görüntüleme izni yok" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Geçersiz veri sağlandı" @@ -112,13 +105,13 @@ msgstr "Tarih giriniz" msgid "Invalid decimal value" msgstr "Geçersiz ondalık değer" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Notlar" @@ -131,75 +124,91 @@ msgstr "'{name}' değeri desen formatında yer almıyor" msgid "Provided value does not match required pattern: " msgstr "Sağlanan değer gerekli kalıpla eşleşmiyor: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Geçersiz grup: {grup}" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Boş seri numarası dizesi" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Yinelenen seri" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "Geçersiz grup: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Seri numarası bulunamadı" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, 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:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Bu değerden HTML etiketlerini kaldır" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Veriler yasaklanmış işaretleme içeriği içeriyor" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Bağlantı hatası" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Sunucu geçersiz durum kodu ile cevap verdi" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "İstisna oluştu" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Sunucu geçersiz Content-Length değeriyle yanıt verdi" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Görsel boyutu çok büyük" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Görsel indirme maksimum boyutu aştı" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Uzak sunucu boş cevap döndü" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "Sağlanan URL geçerli bir görsel dosyası değil" @@ -207,11 +216,11 @@ msgstr "Sağlanan URL geçerli bir görsel dosyası değil" msgid "Log in to the app" msgstr "Uygulamaya giriş yapın" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "E-posta" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 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." @@ -255,133 +264,108 @@ msgstr "Referans {pattern} deseniyle mutlaka eşleşmeli" msgid "Reference number is too large" msgstr "Referans sayısı çok fazla" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Geçersiz seçim" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Adı" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Açıklama" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Yol" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "Aynı kaynak altında birden fazla aynı isim kullanılamaz" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown notları (isteğe bağlı)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Barkod Verisi" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Üçüncü parti barkod verisi" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Barkod Hash" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "Barkod verisinin benzersiz hash'i" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Var olan barkod bulundu" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "Görev Başarısızlığı" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "Arka plan çalışan görevi '{f}' {n} denemeden sonra başarısız oldu" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Sunucu Hatası" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Bir hafta sunucu tarafından kayıt edildi." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Geçerli bir numara olmalı" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Para birimi" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Mevcut seçeneklerden para birimini seçin" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "Bu alan boş olamaz." -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Geçersiz değer" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Uzak Görsel" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "Uzak görselin dosya URL'si" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Uzak URL'den görsel indirme etkin değil" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "Uzak URL'den görsel indirilemedi" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "Geçersiz içerik türü biçimi" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "İçerik türü bulunamadı" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "İçerik türü gerekli mixin sınıfı ile eşleşmemektedir" @@ -537,11 +521,11 @@ msgstr "Çince (Basitleştirilmiş)" msgid "Chinese (Traditional)" msgstr "Çince (Geleneksel)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "Güncelleme mevcut" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "InvenTree için güncelleme mevcut" @@ -553,30 +537,30 @@ msgstr "Geçersiz fiziksel birim" msgid "Not a valid currency code" msgstr "Geçerli bir para birimi kodu değil" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Sipariş Durumu" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Üst Yapım İşi" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "Varyantları Dahil Et" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "Varyantları Dahil Et" msgid "Part" msgstr "Parça" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Kategori" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Kök Üretim" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Bana atandı" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Atanılan Kişi" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "Daha önce oluşturuldu" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "Sonra oluşturuldu" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "Başlangıç tarihi var" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "Başlangıç tarihi önce" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "Başlangıç tarihi sonra" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "Hedef tarihi var" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "Hedef tarihi önce" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "Hedef tarihi sonra" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "Daha önce tamamlandı" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "Sonra tamamlandı" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "En yakın tarih" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "Maksimum Tarih" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "Ağacı Hariç Tut" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "Üretim silinemeden önce iptal edilmelidir" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Sarf Malzemesi" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "İsteğe Bağlı" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Montaj" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "İzlenen" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Test Edilebilir" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "Sipariş Açık" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Tahsis Edildi" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Tüketildi" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Siparişte" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Üretim Emri" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Konum" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "Çıktı" -#: build/api.py:897 +#: build/api.py:983 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:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Üretim Emirleri" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Montaj BOM listesi henüz doğrulanmadı" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "Pasif bir parça için üretim emri oluşturulamaz" -#: build/models.py:192 +#: build/models.py:195 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:210 +#: build/models.py:213 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:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Sorumlu kullanıcı veya grup belirtilmelidir" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "Üretim emri parçası değiştirilemez" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "Hedef tarih başlangıç tarihinden sonra olmalıdır" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Üretim Emri Referansı" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Üretim Emri Referansı" msgid "Reference" msgstr "Referans" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Üretimin kısa açıklaması (isteğe bağlı)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "Bu üretimin tahsis edildiği üretim emri" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Üretilecek parçayı seçin" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Satış Emri Referansı" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "Bu üretimin tahsis edildiği satış siparişi" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Kaynak Konum" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "Harici Üretim" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "Bu üretim emri harici olarak tamamlanmıştır" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Hedef Konum" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "Tamamlanmış ögelerin saklanacağı konumu seçiniz" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Üretim Miktarı" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Üretilecek stok kalemlerinin sayısı" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Tamamlanmış ögeler" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "Tamamlanan stok kalemlerinin sayısı" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "Üretim Durumu" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Üretim durum kodu" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Sıra numarası" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Bu üretim çıktısının parti kodu" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Oluşturulma tarihi" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "Üretim başlangıç tarihi" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "Bu üretim emri için planlanan başlangıç tarihi" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Hedef tamamlama tarihi" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Tamamlama tarihi" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "tamamlayan" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Düzenleyen" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "Bu üretim emrini düzenleyen kullanıcı" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Sorumlu" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "Bu üretim emrinden sorumlu kullanıcı veya grup" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Harici Bağlantı" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Harici URL'ye bağlantı" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Üretim Önceliği" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Bu üretim emrinin önceliği" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Proje Kodu" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Bu üretim emri için proje kodu" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "Açık alt üretim işlemleri varken üretim emri tamamlanamaz" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "Eksik çıktılar varken üretim emri tamamlanamaz" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "{build} üretim emri tamamlandı" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "Bir üretim emri tamamlandı" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "İzlenebilir parçalar için seri numaraları sağlanmalıdır" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Hiçbir üretim çıktısı belirtilmedi" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Üretim çıktısı zaten tamamlanmış" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "Üretim çıktısı, üretim emri ile eşleşmiyor" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Miktar sıfırdan büyük olmalıdır" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "Miktar çıktı miktarından büyük olamaz" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "Üretim çıktısı tüm gerekli testleri geçmedi" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "Tahsis edilen stok kalemleri hâlâ üretimde" -#: build/models.py:1208 +#: build/models.py:1221 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:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Üretim Emri Satırı" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Üretim nesnesi" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Miktar" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Üretim emri için gereken miktar" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "Tüketilen Stok Miktarı" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "Seçilen stok kalemi BOM satırı ile eşleşmiyor" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "Tahsis edilen miktar sıfırdan büyük olmalıdır" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Seri numaralı stok için miktar bir olmalı" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Stok kalemi fazladan tahsis edilmiş" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Stok Kalemi" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Kaynak stok kalemi" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "Üretime tahsis edilecek stok miktarı" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Kur" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Hedef stok kalemi" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Üretim Seviyesi" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Parça Adı" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Üretim Çıktısı" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "Üretim çıktısı üst üretim ile eşleşmiyor" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "Çıktı parçası üretim emri parçası ile eşleşmiyor" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "Bu üretim çıktısı zaten tamamlandı" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "Bu üretim çıktısı tam tahsis edilmedi" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Üretim çıktısının miktarını girin" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "İzlenebilir parçalar için tamsayı miktar gerekir" -#: build/serializers.py:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Seri Numaraları" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "Üretim çıktıları için seri numaraları girin" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Üretim çıktısı için stok konumu" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Seri Numaralarını Otomatik Tahsis Et" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "Eşleşen seri numaralı gerekli kalemleri otomatik tahsis et" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "Şu seri numaraları zaten varlar veya geçersizler" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "Bir üretim çıktıları listesi sağlanmalıdır" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Hurdaya ayrılan çıktılar için stok konumu" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Ayırmaları İptal Et" -#: build/serializers.py:495 +#: build/serializers.py:501 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" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Üretim çıktı(larını) hurdaya ayırma nedeni" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Tamamlanan üretim çıktıları içi konum" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Tamamlanmamış Ayırmayı Onayla" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "Stok henüz tamamen tahsis edilmemşse çıktıları tamamla" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Tahsis Edilen Stoku Tüket" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Tamamlanmamış Çıktıları Kaldır" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "Henüz tamamlanmamış tüm üretim çıktılarını sil" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "İzin verilmedi" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "Bu üretim emri tarafından tüketildi olarak kabul et" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "Bu üretim emrini tamamlamadan önce tahsisi kaldır" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Aşırı Tahsis Edilmiş Stok" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "Bazı stok kalemleri aşırı tahsis edilmiştir" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Tahsis Edilmeyeni Kabul Et" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "Gerekli stok tamamen tahsis edilemedi" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Tamamlanmamış Kabul et" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "Gereken üretim miktarı tamamlanmadı" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "Üretim emrinin açık alt üretim emirleri var" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "Üretim emri üretim durumunda olmalıdır" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "Üretim emrinde eksik çıktılar var" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Üretim Satırı" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Üretim çıktısı" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "Üretim çıktısı aynı üretimi göstermelidir" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Üretim Satırı" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Kalem stokta olmalıdır" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Ayrılma ögeleri sağlanmalıdır" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Konumu Hariç Tut" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "Bu seçilen konumdan stok kalemlerini hariç tut" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Birbirinin Yerine Kullanılabilir Stok" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Birden fazla konumdaki stok kalemleri birbirinin yerine kullanılabilir" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Yedek Stok" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Yedek parçaların ayrılmasına izin ver" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "İsteğe Bağlı Ögeler" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "İsteğe bağlı BOM kalemlerini üretim emrine tahsis et" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "Tüm Ögeler" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "Takip edilmeyen kalemler" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "Takipli Kalemler" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "Kalem Türü" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Otomatik tahsis edilecek ürün tipini seçin" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Otomatik ayırma görevini başlatma başarısız oldu" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "ML Referansı" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "BOM Parça ID" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "ML Parça Adı" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "Kur" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "Yap" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Tedarikçi Parçası" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Tahsis Edilen Miktar" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Üretim Referansı" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Parça Kategorisi Adı" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Takip Edilebilir" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Devralınmış" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Varyantlara İzin Ver" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "ML Ögesi" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Üretimde" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "Üretim için Planlandı" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Harici Stok" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Mevcut Stok" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Mevcut Yedek Stok" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Mevcut Varyant Stok" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "Tüketilen miktar tahsis edilen miktarı aşıyor" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "Stok tüketimi için isteğe bağlı notlar" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "Üretim kalemi doğru üretim emrini göstermelidir" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "Üretim kalemi tahsisini yinele" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "Üretim satırı doğru üretim emrini göstermelidir" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "Üretim satırı tahsisini yinele" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "En az bir kalem veya satır sağlanmalıdır" @@ -1495,43 +1479,47 @@ msgstr "Beklemede" msgid "Cancelled" msgstr "İptal edildi" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Tamamlandı" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Üretim emri için gereken stok" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Üretim emri {build} ek stok gerektiriyor" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Geciken Üretim Emri" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "{bo} üretim emri şimdi gecikti" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "Link Olanlar" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "Dosya Olanlar" -#: common/api.py:766 +#: common/api.py:777 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:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Kullanıcının bu eki silmek için izni yok" @@ -1551,798 +1539,822 @@ msgstr "Geçerli bir para birimi kodu sağlanmamış" msgid "No plugin" msgstr "Eklenti yok" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Proje Kodu Etiketi" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Güncellendi" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Son güncellemenin zaman damgası" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "Güncelleyen" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "Bu nesneyi en son güncelleyen kullanıcı" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Eşsiz proje kodu" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Proje açıklaması" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "Bu projeden sorumlu kullanıcı veya grup" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "Ayarlar anahtarı" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Ayarlar değeri" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Değer bir boolean değer olmalıdır" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "Değer bir integer değer olmalıdır" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "Değer geçerli bir sayı olmalıdır" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "Değer doğrulama kontrollerini geçemiyor" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Anahtar dizesi benzersiz olmalı" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Kullanıcı" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Fiyat kademesi miktarı" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Fiyat" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Belirtilen miktardaki birim fiyat" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Bitiş Noktası" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Bu web kancası için ad" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Aktif" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Bu web kancası aktif mi" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Token" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Erişim için belirteç" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Gizli" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "HMAC için paylaşılan gizli bilgi" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Mesaj ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Bu mesaj için benzersiz tanımlayıcı" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Sağlayıcı" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Bu mesajın alındığı ana bilgisayar" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Başlık" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Bu mesajın başlığı" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Gövde" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Bu mesajın gövdesi" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "Bu mesajın alındığı uç nokta" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Üzerinde çalışıldı" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "Bu mesajdaki iş bitirildi mi?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "Kimlik" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Başlık" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Bağlantı" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Yayınlandı" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Yazar" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Özet" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Oku" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Haberi okudunuz mu?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Görsel dosyası" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "Bu görsel için hedef model türü" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "Bu görsel için hedef model ID" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "Özel Birim" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "Birim simgesi benzersiz olmalıdır" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "Birim adı geçerli bir tanımlayıcı olmalıdır" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Birim adı" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Sembol" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "İsteğe bağlı birim simgesi" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Tanımlama" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Birim tanımlaması" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Ek" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Eksik dosya" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Bozuk dış bağlantı" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "Model türü" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "Görsel için hedef model türü" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Eklenecek dosyayı seç" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Yorum" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "Ek yorumu" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Yükleme tarihi" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Dosyanın yüklendiği tarih" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Dosya Boyutu" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Bayt cinsinden dosya boyutu" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "Ek için belirtilen model türü geçersiz" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "Özel Durum" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "Özel Durumlar" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "Referans Durum Seti" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "Bu özel durum ile genişletilen durum seti" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Mantıksal anahtar" -#: common/models.py:2108 +#: common/models.py:2190 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:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Değer" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "Modeller veritabanına kaydedilecek sayısal değer" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "Durumun adı" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Etiket" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "Ön yüzde gösterilecek etiket" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Renk" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "Ön yüzde gösterilecek renk" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Model" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "Bu durumun ilişkilendirildiği model" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "Model seçilmelidir" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "Anahtar Seçilmelidir" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "Mantıksal anahtar seçilmelidir" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "Anahtar, mantık anahtarından farklı olmalıdır" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "Geçerli bir referans durum sınıfı sağlanmalıdır" -#: common/models.py:2185 +#: common/models.py:2267 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:2192 +#: common/models.py:2274 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" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "İsim, referans durumunun isimlerinden farklı olmalıdır" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Seçim Listesi" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "Seçim Listeleri" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "Seçim listesinin adı" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "Seçim listesinin açıklaması" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Kilitli" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "Bu seçim listesi kilitli mi?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "Bu seçim listesi kullanılabilir mi?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "Kaynak Eklentisi" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "Seçim listesini sağlayan eklenti" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "Kaynak Dize" -#: common/models.py:2280 +#: common/models.py:2362 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:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "Varsayılan Girdi" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "Bu seçim listesi için varsayılan girdi" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Oluşturuldu" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "Seçim listesinin oluşturulduğu tarih ve saat" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Son Güncelleme" -#: common/models.py:2302 +#: common/models.py:2384 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:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "Seçim Listesi Girdisi" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "Seçim Listesi Girişleri" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "Bu girdinin ait olduğu seçim listesi" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "Seçim listesi girdisinin değeri" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "Seçim listesi girdisi için etiket" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "Seçim listesi girdisinin açıklaması" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "Bu seçim listesi girdisi aktif mi?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Parametre Şablonu" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "Parametre Şablonları" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Onay kutusu parametrelerinin birimleri olamaz" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "Onay kutusu parametrelerinin seçenekleri olamaz" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Seçenekler eşsiz olmalıdır" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Parametre şablon adı benzersiz olmalıdır" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "Bu parametre şablonu için hedef modeli türü" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Parametre Adı" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Birim" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Bu parametre için fiziksel birimler" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Parametre açıklaması" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Onay kutusu" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Bu parametre bir onay kutusu mu?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Seçenekler" -#: common/models.py:2542 +#: common/models.py:2652 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:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "Bu parametre için seçim listesi" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Etkin" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "Bu parametre şablonu etkin mi?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "Parametre" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "Parametreler" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Parametre değeri için geçersiz seçim" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "Parametre için belirtilen model türü geçersiz" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "Model ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "Bu parametre için hedef modelin ID'si" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Şablon" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "Parametre şablonu" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Veri" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Parametre Değeri" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Not" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "İsteğe bağlı not alanı" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "Barkod Taraması" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "Barkod verisi" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "Barkodu taratan kullanıcı" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "Zaman damgası" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "Barkod taramasının tarihi ve saati" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "Barkodu işleyen URL uç noktası" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Bağlam" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "Barkod taraması için bağlam verisi" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "Yanıt" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "Barkod taramasından gelen yanıt verisi" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Sonuç" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "Barkod taraması başarılı mıydı?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "Bir hata oluştu" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "E-posta İletisi" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "E-posta İletileri" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "Duyuruldu" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "Gönderildi" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "Başarısız" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "Teslim edildi" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "Onaylandı" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "Gelen" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "Giden" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "Yanıt Yok" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "Teslimat Takibi" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "Okumayı Takip Et" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "Tıklamayı Takip Et" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3061 +#: common/models.py:3171 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:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "Konu Kimliği" -#: common/models.py:3070 +#: common/models.py:3180 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:3079 +#: common/models.py:3189 msgid "Thread" msgstr "Konu" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "Bu mesaja bağlı konu" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "Öncelik" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "E-Posta Konusu" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "E-posta Konuları" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Anahtar" -#: common/models.py:3148 +#: common/models.py:3258 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:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "Bu konu için benzersiz tanımlayıcı" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "Dahili Olarak Başlatıldı" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "Bu konu dahili olarak mı başlatıldı?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "Konunun oluşturulduğu tarih ve saat" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "Konunun son güncellendiği tarih ve saat" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Teslim Alınan Kalemler" @@ -2392,1235 +2404,1303 @@ msgstr "Ayarın bir ortam değişkeni tarafından üstüne yazılıp yazılmadı msgid "Override" msgstr "Üstüne Yaz" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Çalışıyor" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Bekleyen Görevler" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Planlanan Görevler" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Başarısız Görevler" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "Görev ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "Benzersiz Görev ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Kilit" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Kilit Zamanı" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Görev Adı" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Fonksiyon" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Fonksiyon Adı" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Argümanlar" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Görev Argümanları" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Anahtar Argümanlar" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Anahtar görev argümanları" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Dosya adı" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "Model Tipi" -#: common/serializers.py:718 +#: common/serializers.py:799 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:813 +#: common/serializers.py:895 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:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "Seçim listesi kilitli" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Grup yok" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "Site URL'si yapılandırma tarafından kilitlendi" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Yeniden başlatma gerekli" -#: common/setting/system.py:187 +#: 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" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Bekleyen taşıma işlemleri" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Bekleyen veritabanı taşıma sayısı" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "Aktif uyarı kodları" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "Aktif uyarı kodlarının bir sözlüğü" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "Örnek ID" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "Bu InvenTree örneği için benzersiz tanımlayıcı" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "Duyuru ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "Sunucu durum bilgisinde sunucu ID'sini göster (oturum açılmadan)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Sunucu Örneği adı" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Sunucu örneği için sözce (string) açıklayıcı" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Örnek adını kullan" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Örnek adını başlık çubuğunda kullan" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "`Hakkında` gösterimini kısıtla" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "`Hakkında` kipini yalnızca süper kullanıcılara göster" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Şirket adı" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Dahili şirket adı" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "Ana URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "Sunucu örneğinn temel URL'i" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Varsayılan Para Birimi" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Fiyat hesaplamaları için temel para birimini seçin" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "Desteklenen Para Birimleri" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "Desteklenen para birimi kodlarının listesi" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Para Birimi Güncelleme Aralığı" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "günler" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Para Birimi Güncelleme Eklentisi" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "Kullanılacak para birimi güncelleme eklentisi" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "URL'den indir" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Harici URL'den uzak görseller ve dosyalar indirmeye izin ver" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "İndirme Boyutu Sınırı" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Uzak görsel için izin verilebilir maksimum indirme boyutu" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "URL'den indirmek için kullanılan kullanıcı aracısı" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Harici URL'lerden görsel ve dosya indirirken kullanılan kullanıcı aracısının (user-agent) değiştirilmesine izin ver (varsayılan için boş bırakın)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Sıkı URL Doğrulama" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "URL'leri doğrularken şema tanımlamasını gerekli kıl" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Güncelleme Kontrol Aralığı" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Güncellemeleri şu sıklıkla kontrol et (etkisizleştirmek için sıfır yapın)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Otomatik Yedekleme" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Veritabanı ve ortam dosyalarını otomatik yedeklemeyi etkinleştir" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Otomatik Yedekleme Aralığı" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Otomatik yedekleme olayları arasındaki gün sayısını belirtin" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Görev Silme Aralığı" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Arkaplan görev sonuçları belirtilen gün sayısı kadar sonra silinecektir" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Hata Günlüğü Silme Aralığı" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Hata günlükleri belirtilen gün sayısı kadar sonra silinecektir" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Bildirim Silme Aralığı" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Kullanıcı bildirimleri belirtilen gün sayısı kadar sonra silinecektir" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "E-posta Silme Aralığı" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "E-postalar belirtilen gün sayısı sonrasında silinecektir" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "E-posta Kaydını Koru" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "E-posta kayıt girdilerinin silinmesini engelle" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Barkod Desteği" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Web arayüzünde barkod tarayıcı desteğini etkinleştir" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "Barkod Sonuçlarını Depola" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "Barkod tarama sonuçlarını veritabanına depola" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "Maksimum Barkod Tarama Sayısı" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "Depolanacak maksimum barkod tarama sonuçları sayısı" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Barkod Girdi Gecikmesi" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Barkod girdi işleme gecikme süresi" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Barkod Web Kamerası Desteği" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Tarayıcıda web kamerası aracılığıyla barkod taramaya izin ver" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "Barkod Verisini Göster" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "Barkod verisini tarayıcıda metin olarak görüntüle" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "Barkod Üreteci Eklentisi" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "Dahili barkod üretimi için kullanılacak eklenti" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Parça Revizyonları" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "Parça için revizyon alanını etkinleştir" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "Yalnızca Montaj Revizyonu" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "Yalnızca montaj parçaları için revizyona izin ver" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "Montajdan Silmeye İzin Ver" -#: common/setting/system.py:419 +#: common/setting/system.py:412 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:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "DPN Regex" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Yinelenen DPN'ye İzin Ver" -#: common/setting/system.py:429 +#: common/setting/system.py:422 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:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "DPN Düzenlemeye İzin Ver" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Parça ML Verisini Kopyala" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Parça Parametre Verisini Kopyala" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Parça Test Verisini Kopyala" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Kategori Paremetre Sablonu Kopyala" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "Parça oluştururken kategori parametre şablonlarını kopyala" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Parçaları varsayılan olan şablondur" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Bileşen" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Satın Alınabilir" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Parçalar varsayılan olarak satın alınabilir" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Satılabilir" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Parçalar varsayılan olarak satılabilir" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Parçalar varsayılan olarak takip edilebilir" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Sanal" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Parçalar varsayılan olarak sanaldır" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "İlgili parçaları göster" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "Bir parça için ilgili parçaları görüntüle" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Başlangıç Stok Verisi" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "İlk Tedarikçi Bilgileri" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Parça Adı Görüntüleme Biçimi" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Parça adını görüntüleme biçimi" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "Parça Kategorisi Varsayılan Simgesi" -#: common/setting/system.py:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "Minimum Fiyatlandırma Ondalık Basamakları" -#: common/setting/system.py:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Maksimum Fiyatlandırma Ondalık Basamakları" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Tedarikçi Fiyatlandırmasını Kullan" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Tedarikçi fiyat kademelerini genel fiyat hesaplamalarına dahil et" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Satın Alma Geçmişini Geçersiz Kılma" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Stok Kalemi Fiyatlandırmasını Kullan" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Stok Kalemi Fiyatlandırma Süresi" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Varyant Fiyatlandırması Kullan" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "Genel fiyat hesaplamalarına varyant fiyatlarını dahil et" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Yalnızca Aktif Varyantlar" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "Fiyatlandırmayı Otomatik Güncelle" -#: common/setting/system.py:614 +#: common/setting/system.py:607 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:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Fiyatlandırmayı Yeniden Oluşturma Aralığı" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Dahili Fiyatlar" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Parçalar için dahili fiyatları etkinleştir" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Dahili Fiyat Geçersiz Kılma" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "Malzeme listesinde sıfır miktara izin ver" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Etiket yazdırmayı etkinleştir" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "Web arayüzünden etiket yazdırmayı etkinleştir" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "Etiket Görseli DPI Değeri" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Raporları Etkinleştir" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Rapor üretimini etkinleştir" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Hata Ayıklama Modu" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "Raporları hata ayıklama modunda oluştur (HTML çıktısı)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "Rapor Hatalarını Günlüğe Kaydet" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "Raporlar üretirken oluşan hataları günlüğe kaydet" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Sayfa Boyutu" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "PDF raporlar için varsayılan sayfa boyutu" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Parametre Birimlerini Zorunlu Kıl" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Küresel Çapta Benzersiz Seri Numaraları" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Tükenen Stoku Sil" -#: common/setting/system.py:694 +#: common/setting/system.py:695 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:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Parti Kodu Şablonu" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Stok Sona Erme Tarihi" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Stokun sona erme işlevselliğini etkinleştir" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Süresi Dolan Stoku Sat" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Süresi dolan stok satışına izin ver" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Stok Eskime Süresi" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Süresi Dolmuş Stoktan Üretim" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "Süresi dolmuş stok ile üretime izin ver" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Stok Sahipliği Kontrolü" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "Stok konumu ve kalemleri üzerinde sahiplik kontrolünü etkinleştir" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Varsayılan Stok Konumu Simgesi" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Takılı Stok Kalemlerini Göster" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "Stok tablolarında takılı stok kalemlerini görüntüle" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "Kalemlerin kurulumunu yaparken BOM'u kontrol et" -#: common/setting/system.py:751 +#: common/setting/system.py:764 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:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "Stok Dışı Aktarıma İzin Ver" -#: common/setting/system.py:759 +#: common/setting/system.py:772 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Üretim Emri Referans Şablonu" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "Üretim emri referans alanını üretmek için gerekli şablon" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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 "Sorumlu Sahip Gerektir" -#: common/setting/system.py:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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 "Her siparişe sorumlu bir yetkili atanmalıdır." -#: common/setting/system.py:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "Aktif Parça Gerektirir" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "Pasif parçalarla üretim emri oluşturmayı engelle" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "Kilitli Parça Gerekli" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "Kilidi açılmış parçalarla üretim emri oluşturmayı engelle" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "Geçerli BOM gereklidir." -#: common/setting/system.py:790 +#: common/setting/system.py:803 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:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "Kapalı Alt Siparişler Gerekli" -#: common/setting/system.py:797 +#: common/setting/system.py:810 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:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "Harici Üretim Emirleri" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "Harici üretim emri işlevselliğini etkinleştir" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "Testler Geçene Kadar Engelle" -#: common/setting/system.py:811 +#: common/setting/system.py:832 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:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "İade Siparişlerini Etkinleştir" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Kullanıcı arayüzünde iade siparişi işlevselliğini etkinleştirin." -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "İade Sipariş referans alanı oluşturmak için gerekli desen" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Tamamlanan İade Siparişlerini Düzenle" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Satış Siparişi Referans Şablonu" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Satış Siparişi Varsayılan Gönderi" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Tamamlanmış Satış Siparişlerini Düzenle" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "Kontrol Gerektiren Gönderi" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "Kalemler kontrol edilene dek gönderilerin tamamlanmasını engelle" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "Gönderilen Siparişleri Tamamlandı Olarak İmle" -#: common/setting/system.py:881 +#: common/setting/system.py:902 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:887 +#: common/setting/system.py:908 +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 "Satın Alma Siparişi Referans Şablonu" -#: common/setting/system.py:889 +#: common/setting/system.py:918 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:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "Tamamlanan Satın Alma Siparişlerini Düzenle" -#: common/setting/system.py:903 +#: common/setting/system.py:932 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:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "Para Birimini Dönüştür" -#: common/setting/system.py:910 +#: common/setting/system.py:939 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:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Satın Alma Siparişlerini Otomatik Tamamla" -#: common/setting/system.py:917 +#: common/setting/system.py:946 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:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Şifremi unuttum seçeneğini etkinleştir" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "Giriş yapma sayfasında şifremi unuttum işlevini etkinleştir" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Kayıt olmayı etkinleştir" -#: common/setting/system.py:931 +#: common/setting/system.py:960 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" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "SSO Etkinleştir" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "Kullanıcı girişi sayfalarında SSO etkinleştir" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "SSO ile kayıt olmayı etkinleştir" -#: common/setting/system.py:944 +#: common/setting/system.py:973 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" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "SSO grup eşitlemeyi etkinleştir" -#: common/setting/system.py:952 +#: common/setting/system.py:981 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:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO grup anahtarı" -#: common/setting/system.py:959 +#: common/setting/system.py:988 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:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSO grup haritası" -#: common/setting/system.py:966 +#: 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 "SSO gruplarından yerel InvenTree gruplarına bir eşleme. Yerel grup yoksa, oluşturulacaktır." -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "SSO dışındaki grupları kaldır" -#: common/setting/system.py:974 +#: 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 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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "E-posta Gerekir" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 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:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "SSO kullanıcıları otomatik doldur" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Postayı iki kez gir" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Şifreyi iki kez gir" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Alanlara izin ver" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Hesap oluştururken grup" -#: common/setting/system.py:1014 +#: 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." 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:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "ÇFKD'yi Zorunlu Kıl" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "Kullanıcıların çok faktörlü kimlik doğrulamasını kullanması gerekmektedir." -#: common/setting/system.py:1026 +#: 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 "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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Başlangıçta eklentileri kontrol et" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Eklenti güncellemelerini kontrol et" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 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:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "URL entegrasyonunu etkinleştir" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "URL yönlendirmesi eklemek için eklentileri etkinleştir" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Gezinti entegrasyonunu etkinleştir" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "Eklentilerin gezintiye entegre edilmesini etkinleştir" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Uygulama entegrasyonunu etkinleştir" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Uygulamalar eklemek için eklentileri etkinleştir" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Zamanlama entegrasyonunu etkinleştir" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "Zamanlanmış görevleri çalıştırmak için eklentileri etkinleştir" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Olay entegrasyonunu etkinleştir" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "Eklentilerin olaylara yanıt verebilmesini etkinleştirin" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "Arayüz entegrasyonunu etkinleştir" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 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:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "Posta entegrasyonunu etkinleştir" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Eklentilerin giden/gelen postaları işlemesini etkinleştir" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "Proje kodlarını etkinleştir" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "Projeleri izlemek için proje kodlarını etkinleştir" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" -msgstr "" +msgstr "Stok Sayımını Etkinleştir" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 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:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Harici Konumları Hariç Tut" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "Harici konumlardaki stok kalemlerini stok geçmişi hesaplamalarının dışında tut" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Otomatik Stok Sayımı Periyodu" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "Otomatik stok geçmişi kaydı arasındaki gün sayısı" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "Eski Stok Geçmişi Girdilerini Sil" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "Belirtilen gün sayısından daha eski stok geçmişi girdilerini sil" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "Stok Geçmişi Silme Aralığı" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "Stok geçmişi girdileri belirtilen gün sayısı sonrasında silinecektir" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "Eski Stok Geçmişi Girdilerini Sil" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +msgstr "Belirtilen gün sayısından daha eski stok geçmişi girdilerini sil" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "Stok Geçmişi Silme Aralığı" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgstr "Stok geçmişi girdileri belirtilen gün sayısı sonrasında silinecektir" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Kullancıların tam isimlerini görüntüle" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "Kullanıcı Profillerini Göster" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "Kullanıcıların Profillerini kendi profil sayfalarında göster" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "Test İstasyon Verisini Etkinleştir" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 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:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "Makine Pingini Etkinleştir" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 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" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:256 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Hata raporları alın" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Sistem hataları için bildirim alın" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "Son kullanılan yazdırma makineleri" -#: common/setting/user.py:262 +#: common/setting/user.py:268 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 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "Tüm modeller" @@ -3965,365 +4061,369 @@ msgstr "Parça Aktif" msgid "Manufacturer is Active" msgstr "Üretici Aktif" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Tedarikçi Parçası Aktif" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" -msgstr "" +msgstr "Ana Tedarikçi Parçası" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Dahili Parça Aktif" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "Tedarikçi Aktif" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Üretici" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Şirket" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "Stoku Var" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Şirketler" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Şirket açıklaması" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Şirketin açıklaması" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "İnternet Sitesi" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "Şirketin web sitesi" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Telefon numarası" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "İletişim telefon numarası" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "İletişim e-posta adresi" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "İletişim" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "İlgili kişi" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Harici şirket bilgisine bağlantı" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "Bu şirket aktif mi?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "Müşteri sitesi" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Bu şirkete ürün satıyor musunuz?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "Tedarikçi mi" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Bu şirketten ürün satın alıyor musunuz?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "Üretici mi" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Bu şirket parça üretiyor mu?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Bu şirket için varsayılan para birimi" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "Vergi Numarası" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "Şirket Vergi Numarası" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Adres" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Adres" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Şirket Seç" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Adres Adı" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Adres girdisini açıklayan başlık" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Birincil Adres" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Birincil adres olarak ayarla" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "1. Satır" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "1. Adres Satırı" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "2. Satır" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "2. Adres Satırı" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Posta Kodu" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Şehir/Bölge" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Posta kodu şehir/bölge" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Eyalet/İlçe" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Eyalet veya ilçe" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Ülke" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Adres ülkesi" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Sevkiyat taşıyıcısı için notlar" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Sevkiyat taşıyıcısı için notlar" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Dahili sevkiyet notları" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Dahili kullanım için sevkiyat notları" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Adres bilgisine bağlantı (harici)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Üretici Parçası" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Temel Parça" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Parça seçin" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Üretici seçin" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "ÜPN" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Üretici Parça Numarası" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "Harici üretici bağlantısı için URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Parça üreticisi açıklaması" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "Paket birimleri sıfırdan büyük olmalıdır" -#: company/models.py:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tedarikçi" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Tedarikçi seçin" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Tedarikçi stok kodu" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "Bu tedarikçi parçası aktif mi?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "Ana" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgstr "Bu, bağlı parça için birincil tedarikçi ürünü mü?" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Parça üreticisi seç" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "Harici tedarikçi parçası bağlantısı için URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Tedarikçi parçası açıklaması" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "temel maliyet" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimum ücret (örneğin stoklama ücreti)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Paketleme" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Parça paketleme" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Paket Miktarı" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "çoklu" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Birden fazla sipariş ver" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Tedarikçiden temin edilebilir miktar" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Temin Edilebilir Miktar Güncellendi" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "Temin edilebilirlik verisinin güncellendiği son tarih" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "Tedarikçi Fiyat Kademesi" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "Bu tedarikçi için kullanılan varsayılan para birimi" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "Şirket Adı" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Stokta" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "Fiyat Kademeleri" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "Veri dışa aktarma sırasında hata oluştu" @@ -4428,67 +4528,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "Kayıt için mevcut veritabanı tanımlayıcısı" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "Sütun zaten bir veritabanı alanına eşlenmiştir" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "Alan zaten bir veri sütununa eşlenmiştir" -#: importer/models.py:466 +#: importer/models.py:473 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:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "Sütun veri dosyasında bulunmuyor" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "Alan hedef modelde bulunmuyor" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "Seçilen alan salt okunurdur" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "Oturumu İçe Aktar" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "Alan" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "Sütun" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "Satır İndeksi" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "Orijinal satır verisi" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "Hatalar" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Geçerli" -#: importer/models.py:833 +#: 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:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "Sağlanan ID ile kayıt bulunamadı" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "Sağlanan ID biçimi geçersiz" @@ -4588,7 +4688,7 @@ msgstr "Her etiket için yazdırılacak kopya sayısı" msgid "Connected" msgstr "Bağlı" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Bilinmeyen" @@ -4692,7 +4792,7 @@ msgstr "Özelliğin anahtarı" msgid "Value of the property" msgstr "Özelliğin değeri" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Grup" @@ -4720,7 +4820,7 @@ msgstr "İlerleme türünün maksimum değeri, tür=ilerleme ise gerekli" msgid "Order Reference" msgstr "Sipariş Referansı" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "Açık" @@ -4728,7 +4828,7 @@ msgstr "Açık" msgid "Has Project Code" msgstr "Proje Kodu Var" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Oluşturan" @@ -4764,57 +4864,69 @@ msgstr "Öncesi Hedef Tarih" msgid "Target Date After" msgstr "Sonrası Hedef Tarih" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "Daha önce güncellendi" + +#: order/api.py:236 +msgid "Updated After" +msgstr "Güncellendi (den sonra)" + +#: order/api.py:287 msgid "Has Pricing" msgstr "Fiyatlandırılmış" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "Öncesinde Tamamlandı" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "Sonrasında Tamamlandı" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "Harici Üretim Emri" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Sipariş" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "Sipariş Tamamlandı" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Dahili Parça" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "Sipariş Bekliyor" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Tamamlandı" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "Sevkiyatı Var" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Satın Alma Siparişi" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Satın Alma Siparişi" msgid "Sales Order" msgstr "Satış Siparişi" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Toplam Fiyat" msgid "Total price for this order" msgstr "Bu sipariş için toplam fiyat" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Sipariş Para Birimi" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Bu sipariş için para birimi (şirket varsayılanını kullanmak için msgid "This order is locked and cannot be modified" msgstr "Bu sipariş kilitli olduğundan değiştirilemez" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "İletişim bilgileri seçilen şirketle eşleşmiyor" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "Başlangıç tarihi hedef tarihinden önce olmalıdır" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "Adres bilgileri seçilen şirketle eşleşmiyor" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Bu sipariş için proje kodu seçin" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Harici sayfaya bağlantı" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "Başlangıç ​​tarihi" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "Bu üretim emri için planlanan başlangıç tarihi" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Hedeflenen tarih" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Düzenleme Tarihi" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Siparişin düzenlendiği tarih" #: order/models.py:506 +msgid "Updated At" +msgstr "Güncellenme Tarihi" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "Bu siparişten sorumlu kullanıcı veya grup" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Bu sipariş için ilgili kişi" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Bu sipariş için şirket adresi" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Sipariş referansı" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Durum" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Satın alma siparişi durumu" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "Ürünlerin sipariş edilmekte olduğu şirket" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Tedarikçi Referansı" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Tedarikçi siparişi referans kodu" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "teslim alan" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Siparişin tamamlandığı tarih" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Hedef" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "Teslim alınan kalemler için varış yeri" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "Parça tedarikçisi PO tedarikçisi ile eşleşmelidir" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "Satır, satın alma siparişi ile eşleşmiyor" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "Satırda bağlantılı bir parça eksik" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Miktar pozitif bir sayı olmalıdır" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Müşteri" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "Ürünlerin satılmakta olduğu şirket" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "Satış siparişi durumu" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Müşteri Referansı " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Müşteri siparişi referans kodu" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Sevkiyat Tarihi" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "tarafından sevk edildi" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "Sipariş zaten tamamlandı" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "Sipariş zaten iptal edildi" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "Yalnızca açık siparişler tamamlandı olarak işaretlenebilir" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Tamamlanmamış sevkiyatlar olduğundan sipariş tamamlanamaz" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Tamamlanmamış tahsisatlar olduğundan sipariş tamamlanamaz" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "Tamamlanmamış satırlar olduğundan sipariş tamamlanamaz" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "Bu sipariş kilitli olduğundan değiştirilemez" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Kalem miktarı" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Satır referansı" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Satır notları" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Satır açıklaması (isteğe bağlı)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Bu satır için ek bağlam" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Birim Fiyat" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "Satın Alma Siparişi Kalemi" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "Tedarikçi parçası tedarikçi ile eşleşmelidir" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "Üretim emri harici olarak işaretlenmelidir" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "Üretim emirleri yalnızca montaj parçalarına bağlanabilir" -#: order/models.py:1910 +#: order/models.py:1977 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:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Tedarikçi parçası" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Teslim Alındı" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Teslim alınan miktar" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Alış Fiyatı" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Birim alış fiyatı" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "Bu kalem tarafından karşılanacak harici Üretim Emri" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "Satış Siparişi Kalemi" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Satış Fiyatı" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Birim satış fiyatı" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Sevk edildi" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Sevk edilen miktar" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "Satış Siparişi Sevkiyatı" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "Sevk adresi müşteri ile eşleşmelidir" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "Bu sevkiyatın sevk adresi" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Sevkiyat tarihi" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Teslimat Tarihi" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Sevkiyatın teslimat tarihi" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Kontrol Eden" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Bu sevkiyatı kontrol eden kullanıcılar" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Sevkiyat" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Sevkiyat numarası" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Takip Numarası" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Sevkiyat takip numarası" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Fatura Numarası" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Fatura referans numarası" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Sevkiyat zaten sevk edildi" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "Sevkiyatın tahsis edilen stok kalemleri bulunmuyor" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "Sevkiyat tamamlanmadan önce kontrol edilmelidir" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "Satış Siparişi Tahsisatı" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Stok kalemi henüz atanmadı" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "Parça içermeyen bir satıra stok tahsis edilemez" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Tahsis miktarı stok miktarını aşamaz" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "Tahsis edilen miktar sıfırdan büyük olmalıdır" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "Seri numaralı stok kalemi için miktar 1 olmalıdır" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "Satış siparişi sevkiyatla eşleşmiyor" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "Sevkiyat satış siparişiyle eşleşmiyor" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "Satır" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Satış siparişinin sevkiyat referansı" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Kalem" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Tahsis edilecek stok kalemini seçin" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Stok tahsis miktarını girin" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "İade Siparişi referansı" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "Ürünlerin iade edildiği şirket" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "İade siparişi durumu" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "İade Siparişi Satırı" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "Stok kalemi belirtilmelidir" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "İade miktarı stok miktarını aşıyor" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "İade miktarı sıfırdan büyük olmalıdır" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "Seri numaralı stok kalemi için geçersiz miktar" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "Müşteriden iade edilecek ürünü seçin" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Teslim Alma Tarihi" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "Bu iade kaleminin teslim alındığı tarih" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Sonuç" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Bu satırın sonucu" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "Sipariş ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "Kopyası oluşturulacak siparişin ID'si" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "Satırları Kopyala" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "Satırları orijinal siparişten kopyala" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "Ek Kalemleri Kopyala" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "Orijinal siparişten ek kalemleri kopyala" -#: order/serializers.py:110 +#: order/serializers.py:96 part/serializers.py:414 +msgid "Copy Parameters" +msgstr "Parametreleri Kopyala" + +#: order/serializers.py:97 +msgid "Copy order parameters from the original order" +msgstr "Parametreleri orijinal siparişten kopyala" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Satırlar" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "Tamamlanan Satırlar" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "Siparişin Kopyasını Oluştur" -#: order/serializers.py:172 +#: 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:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "Geçersiz sipariş ID" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Tedarikçi Adı" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Sipariş iptal edilemez" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "Siparişin eksik satırları var" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Sipariş açık değil" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "Otomatik Fiyatlandırma" -#: order/serializers.py:640 +#: order/serializers.py:679 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:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Satın alma fiyatı para birimi" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "Kalemleri Birleştir" -#: order/serializers.py:678 +#: order/serializers.py:729 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:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "SKU" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Dahili Parça Numarası" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "Dahili Parça Adı" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Tedarikçi parçası belirtilmeli" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Satın alma siparişi belirtilmeli" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Tedarikçi satın alma siparişi ile eşleşmelidir" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Satın alma siparişi tedarikçi ile eşleşmelidir" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Satır" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Teslim alınan kalemler için varış konumunu seçin" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Gelen stok kalemleri için parti numarası girin" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Son Kullanma Tarihi" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "Gelen stok kalemleri için son kullanma tarihi girin" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Gelen stok kalemlerinin seri numaralarını girin" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "Gelen stok kalemlerinin paketleme bilgilerini geçersiz kıl" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "Gelen stok kalemleri için ek not" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Barkod" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Taranan barkod" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Barkod zaten kullanımda" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Satırlar sağlanmalıdır" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Hedef konum belirtilmelidir" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Sağlanan barkod değerleri benzersiz olmalıdır" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "Sevkiyatlar" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Tamamlanan Sevkiyatlar" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" -msgstr "" +msgstr "Tahsis Edilen Kalemler" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Satış para birimi" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "Tahsis Edilen Kalemler" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Sevkiyat bilgileri sağlanmadı" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Miktar pozitif olmalıdır" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Tahsis edilecek seri numaralarını girin" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Sevkiyat zaten sevk edildi" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "Sevkiyat bu sipariş ile ilişkilendirilmemiştir" -#: order/serializers.py:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "Şu seri numaraları mevcut değildir" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "İade siparişi kalemi" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "Ürün kalemi iade siparişi ile eşleşmiyor" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Ürün kalemi zaten teslim alındı" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "İade olacak miktar" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Satır para birimi" @@ -5598,146 +5742,150 @@ msgstr "Geri öde" msgid "Reject" msgstr "Reddet" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Geciken Satın Alma Siparişi" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Satın alma siparişi {po} şimdi gecikti" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Geciken Satış Siparişi" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Satış siparişi {so} şimdi gecikti" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "Gecikmiş İade Siparişi" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "İade siparişi {ro} şimdi gecikti" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "Yıldızlı" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "Yıldızlı kategorilere göre filtrele" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Derinlik" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "Kategori derinliğine göre filtrele" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "Üst Seviye" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "Üst seviye kategorilere göre filtrele" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "Kademeli" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "Filtrelenmiş sonuçlara alt kategorileri dahil et" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Üst" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Üst kategoriye göre filtrele" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "Belirtilen kategorideki alt kategorileri hariç tut" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "Sonuçları Olanlar" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "Varyant mı" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "Revizyon mu" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "Revizyonu Olanlar" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "BOM Geçerli" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "Kategorileri Kademele" -#: part/api.py:970 +#: part/api.py:980 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:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Sayısal kategori ID veya 'null' sabitine göre filtrele" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" -msgstr "" +msgstr "Montaj parçası etkin" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" -msgstr "" +msgstr "Montaj parçası takip edilebilir" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "Montaj test edilebilir" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" -msgstr "" +msgstr "Bileşen etkin" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" -msgstr "" +msgstr "Bileşen takip edilebilir" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "Bileşen test edilebilir" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" -msgstr "" +msgstr "Bileşen bir montaj parçası" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" -msgstr "" +msgstr "Bileşen sanal" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" -msgstr "" +msgstr "Stok mevcut" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "Kullanımlar" @@ -5746,11 +5894,11 @@ msgstr "Kullanımlar" msgid "Part Category" msgstr "Parça Kategorisi" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Parça Kategorileri" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Varsayılan Konum" @@ -5778,7 +5926,7 @@ msgstr "Bu kategoridaki parçalar için varsayılan anahtar kelimeler" msgid "Icon" msgstr "Simge" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Simge (isteğe bağlı)" @@ -5799,1025 +5947,1050 @@ msgstr "Varsayılan Değer" msgid "Default Parameter Value" msgstr "Varsayılan Parametre Değeri" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Parçalar" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "Kilitli bir parçanın parametreleri silinemez" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "Kilitli bir parçanın parametreleri değiştirilemez" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Bu parça kilitli olduğu için silinemez" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Bu parça hala aktif olduğundan silinemez" -#: part/models.py:598 +#: part/models.py:599 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:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, 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:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "Parça, kendisinin revizyonu olamaz" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "Zaten bir revizyon olan bir parçanın revizyonu yapılamaz" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "Revizyon kodu belirtilmelidir" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "Revizyonlara yalnızca montaj parçaları için izin verilir" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "Bir şablon parçanın revizyonu yapılamaz" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "Üst parça aynı şablonu göstermelidir" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "Bu seri numarasına sahip stok kalemi zaten var" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "Yinelenen DPN'ye parça ayarlarında izin verilmiyor" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "Kopyası oluşturulan parça revizyonu zaten var." -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "Bu Ad, IPN ve Revizyona sahip parça zaten var." -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "Parçalar yapısal parça kategorilerine atanamaz!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Parça adı" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Şablon Mu" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Bu parça bir şablon parçası mı?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "Bu parça başka bir parçanın varyantı mı?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Şunun Varyantı" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Anahtar kelimeler" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Parça kategorisi" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "DPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "Parça revizyon veya versiyon numarası" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Revizyon" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "Bu parça başka bir parçanın revizyonu mu?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Şunun Revizyonu" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Bu kalem normalde nerede depolanır?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Varsayılan Son Kullanma" -#: part/models.py:1229 +#: part/models.py:1224 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)" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Minimum Stok" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "İzin verilen minimum stok düzeyi" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Bu parça için ölçü birimleri" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Bu parça diğer parçalardan üretilebilir mi?" -#: part/models.py:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "Bu parçanın benzersiz kalemler için izleme özelliği var mı?" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "Bu parçanın test sonuçları kaydedilebilir mi?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "Bu parça dış tedarikçilerden satın alınabilir mi?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "Bu parça müşterilere satılabilir mi?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Bu parça aktif mi?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "Kilitli parçalar değiştirilemez" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "BOM Doğrulandı" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "Bu parçanın BOM'u geçerli mi?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "BOM sağlama toplamı" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Saklanan BOM sağlama toplamı" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM'u kontrol eden" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "BOM kontrol tarihi" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Oluşturan Kullanıcı" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "Bu parçanın sorumlu sahibi" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Birden fazla sat" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "Fiyat hesaplamalarını önbelleğe almak için kullanılan para birimi" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Minimum BOM Maliyeti" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Bileşenlerin minimum maliyeti" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Maksimum BOM Maliyeti" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Bileşenlerin maksimum maliyeti" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Minimum Satın Alma Maliyeti" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Minimum tarihsel satın alma maliyeti" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Maksimum Satın Alma Maliyeti" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "Maksimum tarihsel satın alma maliyeti" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Minimum Dahili Fiyat" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "Dahili fiyat kademelerine dayalı minimum maliyet" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Maksimum Dahili Fiyat" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "Dahili fiyat kademelerine dayalı maksimum maliyet" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Minimum Tedarikçi Fiyatı" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "Parça için minimum dış tedarikçi fiyatı" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Maksimum Tedarikçi Fiyatı" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "Parça için maksimum dış tedarikçi fiyatı" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Minimum Varyant Maliyeti" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "Varyant parçaların hesaplanan minimum maliyeti" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Maksimum Varyant Maliyeti" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "Varyant parçaların hesaplanan maksimum maliyeti" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Minimum Maliyet" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Minimum maliyeti geçersiz kıl" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Maksimum Maliyet" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Maksimum maliyeti geçersiz kıl" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Hesaplanan genel minimum maliyet" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Hesaplanan genel maksimum maliyet" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Minimum Satış Fiyatı" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "Fiyat kademelerine dayalı minimum satış fiyatı" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Maksimum Satış Fiyatı" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Fiyat kademelerine dayalı maksimum satış fiyatı" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Minimum Satış Maliyeti" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Minimum tarihsel satış fiyatı" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Maksimum Satış Maliyeti" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Maksimum tarihsel satış fiyatı" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Stok sayımı için parça" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Kalem Sayısı" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "Sayım anındaki tekil stok kaydı sayısı" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "Sayım anındaki toplam mevcut stok" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Tarih" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Stok sayımının yapıldığı tarih" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Minimum Stok Maliyeti" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "Mevcut stokun tahmini minimum maliyeti" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Maksimum Stok Maliyeti" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "Mevcut stokun tahmini maksimum maliyeti" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "Parça Satış Fiyat Kademesi" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "Parça Test Şablonu" -#: part/models.py:3651 +#: part/models.py:3665 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:3683 +#: part/models.py:3697 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:3697 +#: part/models.py:3711 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:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Test Adı" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Test için bir ad girin" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "Test Anahtarı" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "Test için basitleştirilmiş anahtar" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Test Açıklaması" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Bu test için açıklama girin" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "Bu test etkinleştirildi mi?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Gerekli" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Testi geçmesi için bu gerekli mi?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Değer Gerektirir" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Ek Gerektirir" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 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:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +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 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM kalemi değiştirilemez - montaj kilitlidir" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM kalemi değiştirilemez - varyant montajı kilitlidir" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Üst parçayı seçin" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Alt parça" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "BOM'da kullanılacak parçayı seçin" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Bu BOM kalemi için BOM miktarı" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Bu BOM kalemi isteğe bağlıdır" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "Hazırlık Payı" -#: part/models.py:4014 +#: part/models.py:4091 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:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "Fire" -#: part/models.py:4024 +#: part/models.py:4101 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:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "Kat Yuvarlama" -#: part/models.py:4037 +#: part/models.py:4114 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:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "BOM kalemi referansı" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "BOM kalemi notları" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Sağlama Toplamı" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "BOM satırı sağlama toplamı" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Doğrulandı" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Bu BOM kalemi doğrulandı" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Devralınır" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "İzlenebilir parçalar için miktar tamsayı olmalıdır" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Alt parça belirtilmelidir" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "BOM Kalemi Muadili" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Üst BOM kalemi" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Muadil parça" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Parça 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Parça 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "İlgili Parçayı Seçin" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "Bu ilişki için not" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Kopyalanan ilişki zaten mevcut" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "Üst Kategori" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "Üst parça kategorisi" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Alt kategoriler" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Sonuçlar" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "Bu şablon ile ilişkilendirilmiş sonuç sayısı" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "Bu stok kaleminin alış para birimi" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "Dosya bir görsel değil" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Orijinal Parça" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "Kopyalanacak orijinal parçayı seçin" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Görseli Kopyala" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "Orijinal parçadan görseli kopyala" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "BOM'u Kopyala" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Parametreleri Kopyala" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "Orijinal parçadan parametreleri kopyala" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Notları Kopyala" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "Orijinal parçadan notları kopyala" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "Testleri Kopyala" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "Orijinal parçadan test şablonlarını kopyala" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Başlangıç Stok Miktarı" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Başlangıç Stok Konumu" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "Bu parça için başlangıç stok konumunu belirtin" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Tedarikçiyi seçin (veya atlamak için boş bırakın)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "Üreticiyi seçin (veya atlamak için boş bırakın)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Üretici parça numarası" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "Seçilen şirket geçerli bir tedarikçi değildir" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "Seçilen şirket geçerli bir üretici değildir" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "Bu MPN ile eşleşen üretici parçası zaten mevcut" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "Bu SKU ile tedarikçi parçası zaten mevcut" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Kategori Adı" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Üretiliyor" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "Bu parçanın şu anda üretimde olan miktarı" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Bu parçanın üretilmesi planlanan açık miktarı" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Stok Kalemleri" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "Revizyonlar" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Toplam Stok" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "Tahsis Edilmemiş Stok" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "Varyant Stoku" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Parçanın Kopyasını Oluştur" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "Başlangıç verisini diğer parçadan kopyala" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Başlangıç Stoku" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "Başlangıç stok miktarı ile parça oluştur" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Tedarikçi Bilgileri" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "Bu parça için ilk tedarikçi bilgilerini ekleyin" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Kategori Parametrelerini Kopyala" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "Seçilen parça kategorisinden parametre şablonlarını kopyala" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Mevcut Görsel" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "Mevcut parça görselinin dosya adı" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Görsel dosyası mevcut değil" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Tüm ürün ağacını doğrula" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Üretebilir Miktar" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "Üretim Emirleri için Gerekli" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "Üretim Emirlerine Tahsis Edildi" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "Satış Siparişleri için Gerekli" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "Satış Siparişlerine Tahsis Edildi" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" -msgstr "" +msgstr "Parça DPN" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "Parça Açıklaması" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "Stok sayımı bilgisi oluşturmak üzere bir parça (ve varsa varyantlarını) seçin" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "Kategorideki (ve alt kategorilerdeki) tüm parçaları dahil etmek için bir kategori seçin" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "Konumda (ve alt konumlarda) stoğu bulunan tüm parçaları dahil etmek için bir konum seçin" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "Stok Sayımı Kayıtları Oluşturun" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "Seçili parçalar için stok sayımı girdilerini kaydedin" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" -msgstr "" +msgstr "Rapor Oluştur" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" -msgstr "" +msgstr "Seçili parçalar için stok sayımı raporu oluşturun" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Minimum Fiyat" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Minimum fiyat için hesaplanan değeri geçersiz kıl" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Minimum fiyat para birimi" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Maksimum Fiyat" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Maksimum fiyat için hesaplanan değeri geçersiz kıl" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Maksimum fiyat para birimi" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Güncelle" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Bu parçanın fiyatlandırmasını güncelle" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "Minimum fiyat maksimum fiyattan yüksek olamaz" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "Maksimum fiyat minimum fiyattan düşük olamaz" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "Üst montajı seçin" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "Bileşeni seçin" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "BOM'u kopyalanacak parçayı seçin" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Mevcut Verileri Temizle" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "Kopyalamadan önce mevcut BOM kalemlerini temizle" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Devralınanı Dahil Et" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "Şablon parçalardan devralınan BOM kalemlerini dahil et" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Geçersiz Satırları Atla" -#: part/serializers.py:1918 +#: part/serializers.py:2010 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:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Muadil Parçaları Kopyala" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "BOM kalemlerinin kopyasını oluştururken muadil parçaları kopyala" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Düşük stok bildirimi" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "Eskimiş stok bildirimi" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "Geçerlilik tarihi yaklaşan 1 adet stok kaleminiz var" -#: part/tasks.py:79 +#: part/tasks.py:80 #, 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" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "Geçerlilik tarihi yok" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} Gün önce süresi doldu" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "Süresi bugün doluyor" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} gün" @@ -7031,15 +7204,15 @@ msgstr "Tahsis edilecek miktar" msgid "Label printing failed" msgstr "Etiket yazdırılamadı" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "Etiket PDF olarak işlenirken hata oluştu" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "Etiket HTML olarak işlenirken hata oluştu" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "Yazdırılacak öge seçilmedi" @@ -7100,7 +7273,7 @@ msgstr "Barkodlar için yerleşik destek sağlar" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "Değişen parça bildirimi" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "`{part.name}` parçası, `{part_action}` olayı ile tetiklenmiştir" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF etiket yazıcı" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Hata ayıklama modu" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 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" @@ -7500,7 +7673,7 @@ msgstr "Kenarlık" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Yatay" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" -msgstr "Eklentileri yalnızca yetkili personel yönetebilir" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "Eklenti kurulumu devre dışı bırakıldı" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Eklenti kurulumu başarılı" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Eklenti {path} yoluna kuruldu" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "Eklenti kayıt defterinde bulunamadı" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "Eklenti paketlenmiş bir eklenti değildir" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "Eklenti paketi adı bulunamadı" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "Eklentileri yalnızca yetkili personel yönetebilir" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "Eklenti kaldırma devre dışı bırakıldı" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Bu eklenti şu an aktif olduğundan kaldırılamaz" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Eklenti zorunlu olduğu için kaldırılamaz" -#: plugin/installer.py:352 +#: plugin/installer.py:362 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:357 +#: plugin/installer.py:367 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:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "Eklenti kurulu değil" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "Eklenti kurulumu bulunamadı" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "Eklenti başarıyla kaldırıldı" @@ -7689,21 +7875,21 @@ msgstr "Paket Eklenti" msgid "Plugin" msgstr "Eklenti" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Yazar bulunamadı" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Eklenti en az {v} sürümünü gerektirir" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Eklenti en fazla {v} sürümünü gerektirir" @@ -7884,55 +8070,55 @@ msgstr "Kurulum onaylanmadı" msgid "Either packagename or URL must be provided" msgstr "Paket adı veya URL'den biri belirtilmelidir" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Tam yeniden yükleme" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "Eklenti kayıt defterini tamamen yeniden yükle" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Yeniden yüklemeye zorla" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "Eklenti kayıt defterini, zaten yüklenmiş olsa bile yeniden yüklemeye zorla" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "Eklentileri topla" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "Eklentileri topla ve kayıt defterine ekle" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Eklentiyi Aktifleştir" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Bu eklentiyi aktifleştir" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "Zorunlu eklenti pasifleştirilemez" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "Yapılandırmayı sil" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "Eklenti yapılandırmasını veritabanından sil" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "Bu ayarların uygulanacağı kullanıcı" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "Kalemler" @@ -7948,7 +8134,7 @@ msgstr "Eklenti, etiket yazdırmayı desteklemiyor" msgid "Invalid label dimensions" msgstr "Geçersiz etiket boyutları" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "Şablona geçerli öge sağlanmadı" @@ -7962,162 +8148,166 @@ msgstr "A3" #: report/helpers.py:45 msgid "Legal" -msgstr "" +msgstr "Yasal" #: report/helpers.py:46 msgid "Letter" -msgstr "" +msgstr "Harf" #: report/models.py:128 msgid "Template file with this name already exists" msgstr "Aynı isimde bir şablon zaten mevcut" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Şablon adı" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "Şablon açıklaması" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "Revizyon numarası (otomatik artar)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "Yazdırmada Modele Ekle" -#: report/models.py:237 +#: report/models.py:240 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:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Dosya Adı Deseni" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "Dosya adları oluşturmak için desen" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "Şablon etkinleştirildi" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "Şablon için hedef model türü" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Filtreler" -#: report/models.py:315 +#: report/models.py:320 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:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "Şablon dosyası" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "PDF raporları için sayfa boyutu" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Raporu yatay yönde işle" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "Birleştir" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "Seçili ögeler için tek bir rapor oluştur" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "{self.name} şablonundan oluşturulan rapor" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "Şablon sözdizimi hatası" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "Rapor işleme hatası" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "Rapor oluşturma hatası" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "Rapor çıktılarını birleştirme hatası" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Genişlik [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Etiket genişliği mm olarak belirtilmeli" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Yükseklik [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Etiket yüksekliği mm olarak belirtilmeli" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "Etiket yazdırma hatası" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Parçacık" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Rapor parçacık dosyası" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Parçacık dosyası açıklaması" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Kaynak Dosyası" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Rapor kaynak dosyası" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Kaynak dosyası açıklaması" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "Rapor şablonu seç" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "Rapora dahil edilecek öge birincil anahtarlarının listesi" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "Etiket Şablonu Seç" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "Yazdırma Eklentisi" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "Etiket yazdırma için kullanılacak eklentiyi seç" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seri Numara" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Takılı Kalemler" @@ -8248,222 +8438,234 @@ msgstr "Sonuç yok (gerekli)" msgid "No result" msgstr "Sonuç yok" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "Kaynak dosyası mevcut değil" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Görsel dosyası bulunumadı" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "part_image etiketi bir parça örneği gerektirir" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "company_image etiketi bir şirket örneği gerektirir" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "Konum derinliğine göre filtrele" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "Üst seviye konumlara göre filtrele" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "Filtrelenmiş sonuçlara alt konumları dahil et" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "Üst Konum" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "Üst konuma göre filtrele" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "Parça adı (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:611 +#: stock/api.py:610 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:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "Parça adı (regex)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "Parça IPN (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:628 +#: stock/api.py:627 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:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "Parça IPN (regex)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "Minimum stok" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "Maksimum stok" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Durum Kodu" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Harici Konum" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "Üretim Emrine göre Tüketilenler" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" -msgstr "" +msgstr "Başka bir stok kalemine bağlı" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" -msgstr "" +msgstr "Parça Ağacı" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" -msgstr "" +msgstr "Daha önce güncellendi" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" -msgstr "" +msgstr "Güncellendi (den sonra)" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" -msgstr "" +msgstr "Stok Sayımı (-dan önce)" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" -msgstr "" +msgstr "Stok Sayımı (-dan sonra)" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" -msgstr "" +msgstr "Son kullanma tarihi öncesi" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" -msgstr "" +msgstr "Son kullanma tarihi sonrası" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" -msgstr "" +msgstr "Bozuk" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" +msgstr "Bu stok kalemini ve bağlı tüm alt kalemleri hariç tutmak için bir PK girin" + +#: stock/api.py:980 +msgid "Cascade Locations" +msgstr "Konumları alt konumlara uygula" #: stock/api.py:981 -msgid "Cascade Locations" -msgstr "" - -#: stock/api.py:982 msgid "If true, include items in child locations of the given location" -msgstr "" +msgstr "Açıksa belirtilen konumun alt konumlarındaki öğeleri de dahil eder" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" -msgstr "" +msgstr "Sayısal konum ID'si veya \"null\" değeriyle filtreleyin" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" -msgstr "" +msgstr "Miktar gereklidir" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" -msgstr "" +msgstr "Geçerli bir parça girilmelidir" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" -msgstr "" +msgstr "Belirtilen tedarikçi parçası bulunamadı" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" -msgstr "" +msgstr "Tedarikçi parçası için paket boyutu tanımlanmış, ancak ‘use_pack_size’ seçeneği etkin değil" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" -msgstr "" +msgstr "Takibi olmayan bir parça için seri numarası verilemez" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" -msgstr "" +msgstr "Takılıyı Dahil Et" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" -msgstr "" +msgstr "Aktifse verilen stok kaleminin altına takılı öğelerin test sonuçları da dahil edilir" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" -msgstr "" +msgstr "Sayısal Stok Kalemi ID’sine göre Filtrele" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" -msgstr "" +msgstr "Belirtilen ID {id} ile bir stok kalemi bulunamadı" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" -msgstr "" +msgstr "Varyantları Dahil Et" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" -msgstr "" +msgstr "(-den sonra) sil" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" -msgstr "" +msgstr "Önce" #: stock/models.py:73 msgid "Stock Location type" -msgstr "" +msgstr "Stok Konumu Türü" #: stock/models.py:74 msgid "Stock Location types" -msgstr "" +msgstr "Stok Konum Türleri" #: stock/models.py:100 msgid "Default icon for all locations that have no icon set (optional)" -msgstr "" +msgstr "Simge atanmamış tüm konumlar için varsayılan simge (isteğe bağlı)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Stok Konumu" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Stok Konumları" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" -msgstr "" +msgstr "Sahip" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" -msgstr "" +msgstr "Sahibi Seçin" #: stock/models.py:206 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." -msgstr "" +msgstr "Stok kalemleri yapısal stok konumlarına doğrudan yerleştirilemez; ancak alt konumlara yerleştirilebilir." -#: stock/models.py:213 users/models.py:497 +#: stock/models.py:213 users/models.py:495 msgid "External" -msgstr "" +msgstr "Harici" #: stock/models.py:214 msgid "This is an external stock location" @@ -8481,274 +8683,282 @@ msgstr "Bu konumun stok konumu türü" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} mevcut değil" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "Parça belirtilmelidir" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "Stok kalemleri yapısal stok konumlarına yerleştirilemez!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "Sanal parçalar için stok kalemi oluşturulamaz" -#: stock/models.py:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "Seri numarası olan ögenin miktarı bir olmalı" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Miktar birden büyük ise seri numarası ayarlanamaz" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Öge kendisine ait olamaz" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "Üretim referansı aynı parça nesnesini göstermiyor" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Üst Stok Kalemi" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Temel parça" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Bu stok kalemi nerede bulunur?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "Bu stok kaleminin ambalajı şu şekilde saklanmaktadır" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Şuna Takıldı" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "Bu öge başka bir ögeye takılı mı?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Bu öge için seri numarası" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" -msgstr "" +msgstr "Bu stok kalemine ait parti kodu" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" -msgstr "" - -#: stock/models.py:1124 -msgid "Source Build" -msgstr "" - -#: stock/models.py:1127 -msgid "Build for this stock item" -msgstr "" - -#: stock/models.py:1134 -msgid "Consumed By" -msgstr "" - -#: stock/models.py:1137 -msgid "Build order which consumed this stock item" -msgstr "" - -#: stock/models.py:1146 -msgid "Source Purchase Order" -msgstr "" +msgstr "Stok Miktarı" #: stock/models.py:1150 +msgid "Source Build" +msgstr "Kaynak Üretim" + +#: stock/models.py:1153 +msgid "Build for this stock item" +msgstr "Bu stok kalemi için üretim kaydı" + +#: stock/models.py:1160 +msgid "Consumed By" +msgstr "Tüketen" + +#: stock/models.py:1163 +msgid "Build order which consumed this stock item" +msgstr "Bu stok kaleminin kullanıldığı üretim emri" + +#: stock/models.py:1172 +msgid "Source Purchase Order" +msgstr "Kaynak Satın Alma Emri" + +#: stock/models.py:1176 msgid "Purchase order for this stock item" -msgstr "" +msgstr "Bu stok kalemi için satın alma emri" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" -msgstr "" +msgstr "Hedef satış siparişi" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" -msgstr "" +msgstr "Stok kalemi için son kullanma tarihi. Bu tarihten sonra stok süresi dolmuş kabul edilir" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" -msgstr "" +msgstr "Tükendiğinde sil" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" -msgstr "" +msgstr "Stok tükendiğinde bu stok kalemini sil" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" -msgstr "" +msgstr "Satın alma anındaki birim alış fiyatı" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" -msgstr "" +msgstr "Parçaya dönüştürüldü" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" -msgstr "" +msgstr "Miktar, mevcut stoğu aşıyor" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" -msgstr "" +msgstr "Parça için izlenebilirlik etkin değil" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" -msgstr "" +msgstr "Miktar tam sayı olmalıdır" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" -msgstr "" +msgstr "Miktar, mevcut stok miktarını ({self.quantity}) aşmamalıdır" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" -msgstr "" +msgstr "Seri numaraları liste halinde girilmelidir" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Miktar seri numaları ile eşleşmiyor" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" -msgstr "" +msgstr "Stok, yapısal bir konuma atanamaz" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" -msgstr "" +msgstr "Test şablonu mevcut değil" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" -msgstr "" +msgstr "Stok kalemi bir satış siparişine atanmıştır" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" -msgstr "" +msgstr "Stok kalemi başka bir stok kalemine takılıdır" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" -msgstr "" +msgstr "Bu öge, başka ögeler de içeriyor" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stok kalemi stokta olmadığı için taşınamaz" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,248 +9002,248 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Tedarikçi Parça Numarası" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" -msgstr "" +msgstr "Bu parçaya seri numarası atanamaz" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Seri numaraları zaten mevcut" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" -msgstr "" +msgstr "Takılacak stok kalemini seçin" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" -msgstr "" +msgstr "Miktar" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" -msgstr "" +msgstr "Takılacak kalemlerin miktarını girin" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "İşlem notu ekle (isteğe bağlı)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" -msgstr "" +msgstr "Miktar en az \"1\" olmalıdır" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" -msgstr "" +msgstr "Stok kalemi mevcut değil" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" -msgstr "" +msgstr "Seçilen parça malzeme listesinde bulunamadı" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" -msgstr "" +msgstr "Takılacak miktar, mevcudu geçmemeli" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" -msgstr "" +msgstr "Sökülen ürün için hedef konum" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" -msgstr "" +msgstr "Stok kaleminin dönüştürüleceği parçayı seçin" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" -msgstr "" +msgstr "Seçilen parça dönüştürülmeye uygun değil" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" +msgstr "Tedarikçi parçası atanmış stok kalemi dönüştürülemez" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" -msgstr "" +msgstr "Stok kalemi durum kodu" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" -msgstr "" +msgstr "Durumu değiştirilecek stok kalemlerini seçin" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" -msgstr "" +msgstr "Hiçbir stok kalemi seçilmedi" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Alt konumlar" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" -msgstr "" +msgstr "Üst stok konumu" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" -msgstr "" +msgstr "Parça satılabilir olmalıdır" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" -msgstr "" +msgstr "Ürün bir satış siparişine tahsis edilmiştir" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" -msgstr "" +msgstr "Ürün bir üretim emrine tahsis edilmiştir" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" -msgstr "" +msgstr "Stok kalemlerini atamak için müşteri" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" -msgstr "" +msgstr "Seçilen şirket bir müşteri değil" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" -msgstr "" +msgstr "Stok tahsis notları" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" -msgstr "" +msgstr "Bir stok kalemleri listesi girilmelidir" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" -msgstr "" +msgstr "Stok birleştirme notları" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" -msgstr "" +msgstr "Farklı tedarikçilere izin ver" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" -msgstr "" +msgstr "Farklı tedarikçi parçalarına sahip stokları birleştirmeye izin ver" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" -msgstr "" +msgstr "Farklı durumlara sahip kalemlere izin ver" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" -msgstr "" +msgstr "Farklı durum kodlarına sahip stokları birleştirmeye izin ver" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" -msgstr "" +msgstr "En az iki stok kalemi girilmelidir" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" -msgstr "" +msgstr "Değişiklik Yok" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" -msgstr "" +msgstr "Stok Kalemi birincil anahtar (PK) değeri" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" -msgstr "" +msgstr "Stok kalemi mevcut stokta yok" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" -msgstr "" +msgstr "Stok kalemi zaten stokta" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" -msgstr "" +msgstr "Miktar negatif olamaz" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1826 -msgid "Merge into existing stock" -msgstr "" - -#: stock/serializers.py:1827 -msgid "Merge returned items into existing stock items if possible" -msgstr "" +msgstr "Stok aktarım notları" #: stock/serializers.py:1870 -msgid "Next Serial Number" -msgstr "" +msgid "Merge into existing stock" +msgstr "Mevcut stokla birleştir" -#: stock/serializers.py:1876 +#: stock/serializers.py:1871 +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 +msgid "Next Serial Number" +msgstr "Sıradaki Seri Numarası" + +#: stock/serializers.py:1920 msgid "Previous Serial Number" -msgstr "" +msgstr "Önceki Seri Numarası" #: stock/status_codes.py:11 msgid "OK" @@ -9089,11 +9299,11 @@ msgstr "Stok manuel olarak çıkarıldı" #: stock/status_codes.py:56 msgid "Serialized stock items" -msgstr "" +msgstr "Seri numaralı stok kalemleri" #: stock/status_codes.py:58 msgid "Returned to stock" -msgstr "" +msgstr "Stoğa geri alındı" #: stock/status_codes.py:61 msgid "Location changed" @@ -9133,7 +9343,7 @@ msgstr "Birleştirilen stok kalemleri" #: stock/status_codes.py:79 msgid "Converted to variant" -msgstr "" +msgstr "Varyanta dönüştürüldü" #: stock/status_codes.py:82 msgid "Build order output created" @@ -9145,23 +9355,23 @@ msgstr "Üretim emri çıktısı tamamlandı" #: stock/status_codes.py:84 msgid "Build order output rejected" -msgstr "" +msgstr "Üretim emri çıktısı reddedildi" #: stock/status_codes.py:85 msgid "Consumed by build order" -msgstr "" +msgstr "Üretim emri tarafından tüketildi" #: stock/status_codes.py:88 msgid "Shipped against Sales Order" -msgstr "" +msgstr "Satış siparişi kapsamında sevk edildi" #: stock/status_codes.py:91 msgid "Received against Purchase Order" -msgstr "" +msgstr "Satın alma siparişi kapsamında teslim alındı" #: stock/status_codes.py:94 msgid "Returned against Return Order" -msgstr "" +msgstr "İade siparişine karşılık iade edildi" #: stock/status_codes.py:97 msgid "Sent to customer" @@ -9173,15 +9383,15 @@ msgstr "Müşteriden geri döndü" #: templates/403.html:6 templates/403.html:10 templates/403_csrf.html:7 msgid "Permission Denied" -msgstr "" +msgstr "İzin Reddedildi" #: templates/403.html:11 msgid "You do not have permission to view this page." -msgstr "" +msgstr "Bu sayfayı görüntülemek için izniniz yok." #: templates/403_csrf.html:11 msgid "Authentication Failure" -msgstr "" +msgstr "Kimlik Doğrulaması Başarısız" #: templates/403_csrf.html:12 msgid "You have been logged out from InvenTree." @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "İzinleri ayarla" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Görünüm" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Parçayı görüntüleme izni" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Parça ekleme izni" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Değiştir" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Parçaları düzenleme izni" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Parçaları silme izni" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" -msgstr "" +msgstr "Kullanıcının görünen adı" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" -msgstr "" +msgstr "Konumu" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" -msgstr "" +msgstr "Ana unvanı veya pozisyonu" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" -msgstr "" +msgstr "Kullanıcı durum mesajı" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" -msgstr "" +msgstr "Kullanıcı konum bilgisi" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" -msgstr "" +msgstr "Kullanıcı, sistemi aktif kullanıyor" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" -msgstr "" +msgstr "Kullanıcının tercih edilen iletişim bilgileri" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" -msgstr "" +msgstr "Kullanıcı Türü" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" -msgstr "" +msgstr "Bu, hangi tür kullanıcı?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" -msgstr "" +msgstr "Organizasyon" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" -msgstr "" +msgstr "Kullanıcının ana organizasyonu/ilişkisi" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" -msgstr "" +msgstr "Birincil Grup" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" -msgstr "" +msgstr "Kullanıcının birincil grubu" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" +msgstr "Yönetici" + +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" -#: users/ruleset.py:32 +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Satın Alma Siparişleri" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Satış Siparişleri" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" -msgstr "" +msgstr "İade Emirleri" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Kullanıcı Adı" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Adı" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Kullanıcının adı" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Soyadı" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Kullanıcının soyadı" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Kullanıcının e-posta adresi" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Personel" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Bu kullanıcının personel izinleri var mı" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Süper Kullanıcı" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Bu kullanıcı bir süper kullanıcı mı" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Bu kullanıcı hesabı aktif mi" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" -msgstr "" +msgstr "Bu alanı sadece bir yönetici değiştirebilir" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" -msgstr "" +msgstr "Parola" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" -msgstr "" +msgstr "Kullanıcının parolası" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" -msgstr "" +msgstr "Uyarıları yok say" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" +msgstr "Şifre kuralları uyarılarını yok say" + +#: users/serializers.py:417 +msgid "Staff" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" -msgstr "" +msgstr "Kullanıcı yaratmak için yetkiniz yok" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Kullanıcı hesabınız oluşturulmuştur." -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "Giriş yapmak için lütfen şifre sıfırlama fonksiyonunu kullanınız" -#: users/serializers.py:452 +#: users/serializers.py:497 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 8a0e572d71..6be6d0a2d2 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "Кінцева точка API не знайдена" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "Для масових операцій необхідно надати перелік сутностей або фільтрів" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "Сутності необхідно надати списком" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "Надано неправильний список сутностей" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "Фільтри необхідно надавати у вигляді словника" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "Надано неправильні фільтри" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "Немає сутностей що відповідають наданим критеріям" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "У користувача немає дозволу на перегляд цієї моделі" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "Не вдалося перетворити {original} на {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Невірна кількість" @@ -112,13 +105,13 @@ msgstr "Введіть дату" msgid "Invalid decimal value" msgstr "Неправильне десяткове значення" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Нотатки" @@ -131,75 +124,91 @@ msgstr "Значення '{name}' не відповідає шаблону фо msgid "Provided value does not match required pattern: " msgstr "Надане значення не відповідає обов'язковому шаблону: " -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "Неможливо серіалізувати більше ніж 1000 сутностей за раз" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Пустий серійний номер" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Видаліть HTML тег з цього значення" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "Дані містять заборонений вміст у форматі Markdown" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Помилка підключення" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "Сервер відправив некоректний код статусу" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Відбулося виключення" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "Сервер повернув невірне значення Content-Length" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Розмір зображення занадто великий" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "Розмір зображення перевищує максимально дозволений розмір" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Віддалений сервер повернув пусту відповідь" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "" @@ -207,11 +216,11 @@ msgstr "" msgid "Log in to the app" msgstr "Авторизуватися в додатку" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Електронна пошта" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "Необхідно увімкнути двофакторну автентифікацію, перед тим як робити будь-що інше." @@ -255,133 +264,108 @@ msgstr "" msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Назва" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Опис" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Опис (опціонально)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Шлях" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Примітки в Markdown (опціонально)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Помилка сервера" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Китайська (спрощена)" msgid "Chinese (Traditional)" msgstr "Китайська (Традиційна)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "" msgid "Not a valid currency code" msgstr "" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Деталь" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Розхідний матеріал" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Збірка" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Тестуємо" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Місце" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "" msgid "Reference" msgstr "" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Обрати деталь для створення" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Кількість" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Дозволити варіанти" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "У виробництві" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "" msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "" @@ -1551,798 +1539,822 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Користувач" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Ціна" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Назва" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Посилання" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Коментар" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "Дата завантаження" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "Дата завантаження файлу" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "Розмір файлу" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "Розмір файлу в байтах" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "Етикетка" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "Колір" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "Модель" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "Список вибору" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "Заблоковано" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Прапорець" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Шаблон" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Дані" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Примітка" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Компонент" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Доступний для продажу" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Віртуальний" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Показати пов'язані деталі" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:641 -msgid "Enable label printing" +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 +msgid "Enable label printing" +msgstr "" + +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:889 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:901 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:903 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +msgid "Block Incomplete Item Tests" msgstr "" #: common/setting/system.py:910 -msgid "Convert item value to base currency when receiving stock" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:915 -msgid "Auto Complete Purchase Orders" +#: common/setting/system.py:916 +msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:917 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:924 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:925 -msgid "Enable password forgot function on the login pages" +#: common/setting/system.py:918 +msgid "Required pattern for generating Purchase Order reference field" msgstr "" #: common/setting/system.py:930 -msgid "Enable registration" +msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:931 -msgid "Enable self-registration for users on the login pages" +#: common/setting/system.py:932 +msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:936 -msgid "Enable SSO" +#: common/setting/system.py:938 +msgid "Convert Currency" msgstr "" -#: common/setting/system.py:937 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:942 -msgid "Enable SSO registration" +#: common/setting/system.py:939 +msgid "Convert item value to base currency when receiving stock" msgstr "" #: common/setting/system.py:944 -msgid "Enable self-registration via SSO for users on the login pages" +msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:950 -msgid "Enable SSO group sync" +#: common/setting/system.py:946 +msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:952 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +#: common/setting/system.py:953 +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:958 -msgid "SSO group key" +#: common/setting/system.py:954 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:959 -msgid "The name of the groups claim attribute provided by the IdP" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:964 -msgid "SSO group map" +#: 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 "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:972 -msgid "Remove groups outside of SSO" +#: common/setting/system.py:971 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:974 -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:973 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "" -#: common/setting/system.py:980 -msgid "Email required" +#: common/setting/system.py:979 +msgid "Enable SSO group sync" msgstr "" #: common/setting/system.py:981 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:986 -msgid "Auto-fill SSO users" +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:987 -msgid "Automatically fill out user-details from SSO account-data" +msgid "SSO group key" msgstr "" -#: common/setting/system.py:992 -msgid "Mail twice" +#: common/setting/system.py:988 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" #: common/setting/system.py:993 -msgid "On signup ask users twice for their mail" +msgid "SSO group map" msgstr "" -#: common/setting/system.py:998 -msgid "Password twice" +#: 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:999 -msgid "On signup ask users twice for their password" +#: common/setting/system.py:1001 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1004 -msgid "Allowed domains" +#: 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:1006 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1010 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1012 -msgid "Group on signup" +#: common/setting/system.py:1015 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1014 -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:1020 -msgid "Enforce MFA" +#: common/setting/system.py:1016 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1021 -msgid "Users must use multifactor security." +msgid "Mail twice" msgstr "" -#: common/setting/system.py:1026 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1022 +msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1031 -msgid "Check plugins on startup" +#: common/setting/system.py:1027 +msgid "Password twice" +msgstr "" + +#: common/setting/system.py:1028 +msgid "On signup ask users twice for their password" msgstr "" #: common/setting/system.py:1033 -msgid "Check that all plugins are installed on startup - enable in container environments" +msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1040 -msgid "Check for plugin updates" +#: common/setting/system.py:1035 +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1041 -msgid "Enable periodic checks for updates to installed plugins" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1047 -msgid "Enable URL integration" +#: 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." msgstr "" -#: common/setting/system.py:1048 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1049 +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1054 -msgid "Enable navigation integration" +#: common/setting/system.py:1050 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1055 -msgid "Enable plugins to integrate into navigation" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1061 -msgid "Enable app integration" +#: common/setting/system.py:1060 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1062 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1068 -msgid "Enable schedule integration" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" #: common/setting/system.py:1069 -msgid "Enable plugins to run scheduled tasks" +msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1075 -msgid "Enable event integration" +#: common/setting/system.py:1070 +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1076 -msgid "Enable plugins to respond to internal events" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1082 -msgid "Enable interface integration" +#: common/setting/system.py:1077 +msgid "Enable plugins to add URL routes" msgstr "" #: common/setting/system.py:1083 -msgid "Enable plugins to integrate into the user interface" +msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1089 -msgid "Enable mail integration" +#: common/setting/system.py:1084 +msgid "Enable plugins to integrate into navigation" msgstr "" #: common/setting/system.py:1090 -msgid "Enable plugins to process outgoing/incoming mails" +msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1096 -msgid "Enable project codes" +#: common/setting/system.py:1091 +msgid "Enable plugins to add apps" msgstr "" #: common/setting/system.py:1097 -msgid "Enable project codes for tracking projects" +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1102 -msgid "Enable Stocktake" +#: common/setting/system.py:1098 +msgid "Enable plugins to run scheduled tasks" msgstr "" #: common/setting/system.py:1104 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1110 -msgid "Exclude External Locations" +#: 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 "Exclude stock items in external locations from stocktake calculations" +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1118 -msgid "Automatic Stocktake Period" +msgid "Enable mail integration" msgstr "" #: common/setting/system.py:1119 -msgid "Number of days between automatic stocktake recording" +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1125 -msgid "Delete Old Stocktake Entries" +msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1127 -msgid "Delete stocktake entries older than the specified number of days" +#: 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:1133 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "" + +#: common/setting/system.py:1139 +msgid "Exclude External Locations" +msgstr "" + +#: common/setting/system.py:1141 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "" + +#: common/setting/system.py:1147 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1148 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1154 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1156 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled msgstr "" #: common/setting/user.py:255 -msgid "Receive error reports" +msgid "Show Subassemblies in BOM table" msgstr "" #: common/setting/user.py:256 -msgid "Receive notifications for system errors" +msgid "Enable display of subassemblies in the BOM table" msgstr "" #: common/setting/user.py:261 -msgid "Last used printing machines" +msgid "Receive error reports" msgstr "" #: common/setting/user.py:262 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:267 +msgid "Last used printing machines" +msgstr "" + +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "Позиція активна" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "Позиція постачальника активна" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "Внутрішня позиція активна" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Виробник" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Позиція виробника" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Базова позиція" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Обрати позицію" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "Базова вартість" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Мінімальний платіж (напр. комісія за збереження)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "В наявності" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Дійсно" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Внутрішній компонент" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "" msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "" @@ -4851,718 +4963,750 @@ msgstr "" msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "" -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "" @@ -5598,146 +5742,150 @@ msgstr "" msgid "Reject" msgstr "" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "Глибина" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "Батьківський елемент" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "Фільтр за батьківською категорією" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "" @@ -5778,7 +5926,7 @@ msgstr "" msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "" @@ -5799,1025 +5947,1050 @@ msgstr "" msgid "Default Parameter Value" msgstr "" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Позиції" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "Неможливо видалити цю позицію, оскільки вона заблокована" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "Неможливо видалити цю позицію, оскільки вона ще активна" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "Неможливо видалити цю позицію, бо вона використовується у збірці" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Назва позиції" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Це шаблон" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "Ця позиція є шаблоном?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Опис позиції (опціонально)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Ревізія" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "Ревізія" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Мінімальний запас" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Мінімально дозволений рівень запасів" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Одиниці виміру для цієї позиції" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "Чи можна побудувати цю позицію з інших компонентів?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Дата" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Тестова назва" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Позиція 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Позиція 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "Результати" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Виробничий номер позиції" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Початковий запас" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Наявне зображення" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Мінімальна ціна" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Максимальна ціна" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "" msgid "Label printing failed" msgstr "" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7500,7 +7673,7 @@ msgstr "" msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "" @@ -7580,64 +7753,77 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -7884,55 +8070,55 @@ msgstr "" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8215,7 +8405,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "" @@ -8248,184 +8438,196 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "" msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "" @@ -8461,7 +8663,7 @@ msgstr "" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "" @@ -8481,274 +8683,282 @@ msgstr "" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "" msgid "Revoked" msgstr "" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "" -#: users/ruleset.py:32 -msgid "Purchase Orders" -msgstr "" - -#: users/ruleset.py:33 -msgid "Sales Orders" +#: users/ruleset.py:30 +msgid "Bills of Material" msgstr "" #: users/ruleset.py:34 +msgid "Purchase Orders" +msgstr "" + +#: users/ruleset.py:35 +msgid "Sales Orders" +msgstr "" + +#: users/ruleset.py:36 msgid "Return Orders" msgstr "" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Ім`я" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Прізвище" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Адреса електронної пошти користувача" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Персонал" - -#: users/serializers.py:310 -msgid "Does this user have staff permissions" +#: users/serializers.py:240 +msgid "User must be authenticated" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" + +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:452 +#: users/serializers.py:497 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 4ea506a2db..70077038b0 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:10\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "API endpoint không tồn tại" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "Không có dữ liệu được cung cấp" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 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" @@ -96,7 +88,8 @@ 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:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "Số lượng cung cấp không hợp lệ" @@ -112,13 +105,13 @@ msgstr "Nhập ngày" msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "Ghi chú" @@ -131,75 +124,91 @@ msgstr "Giá trị '{name}' không xuất hiện ở định dạng mẫu" 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:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "Chuỗi số sê-ri trống" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "Trùng lặp sê-ri" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, 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:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "Không tìm thấy số sê-ri" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "Xóa thẻ HTML từ giá trị này" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "Lỗi kết nối" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 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:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "Xảy ra Exception" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 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:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "Hình ảnh quá lớn" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 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:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "Máy chủ trả về phản hồi trống" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 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ệ" @@ -207,11 +216,11 @@ 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:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "" @@ -255,133 +264,108 @@ msgstr "Tham chiếu phải phù hợp với mẫu yêu cầu" msgid "Reference number is too large" msgstr "Số tham chiếu quá lớn" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "Lựa chọn sai" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "Tên" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "Mô tả" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "Mô tả (tùy chọn)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "Đường dẫn" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 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:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Ghi chú markdown (không bắt buộc)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "Dữ liệu mã vạch" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "Dữ liệu mã vạch của bên thứ ba" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "Dữ liệu băm mã vạch" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 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:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "Mã vạch đã tồn tại" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "Lỗi máy chủ" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "Lỗi đã được ghi lại bởi máy chủ." -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "Phải là một số hợp lệ" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "Tiền tệ" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "Chọn tiền tệ trong các tùy chọn đang có" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "Giá trị không hợp lệ" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "Hình ảnh từ xa" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "URL của tệp hình ảnh bên ngoài" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "Chức năng tải hình ảnh từ URL bên ngoài không được bật" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "" @@ -537,11 +521,11 @@ msgstr "Tiếng Trung (Giản thể)" msgid "Chinese (Traditional)" msgstr "Tiếng Trung (Phồn thể)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "" @@ -553,30 +537,30 @@ msgstr "Đơn vị vật lý không hợp lệ" msgid "Not a valid currency code" msgstr "Mã tiền tệ không hợp lệ" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "Trạng thái đặt hàng" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "Phiên bản cha" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "" msgid "Part" msgstr "Nguyên liệu" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "Danh mục" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "Xây dựng nguồn gốc" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "Đã gán cho tôi" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "Đã gán cho" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "" -#: build/api.py:399 +#: build/api.py:414 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:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "Vật tư tiêu hao" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "Tuỳ chọn" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "Lắp ráp" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "Đã theo dõi" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "Có thể kiểm tra" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "Đã cấp phát" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "Đã dùng" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "Bật đơn hàng" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 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:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "Địa điểm" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "Tạo đơn hàng" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "Dây chuyền BOM chưa được xác thực" -#: build/models.py:185 +#: build/models.py:188 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:192 +#: build/models.py:195 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:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "Phải chọn người dùng hoặc nhóm" -#: build/models.py:222 +#: build/models.py:225 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:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "Tham chiếu đơn đặt bản dựng" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "Tham chiếu đơn đặt bản dựng" msgid "Reference" msgstr "Tham chiếu" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "Mô tả ngắn về phiên bạn (Tùy chọn)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "Chọn sản phẩm để xây dựng" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "Tham chiếu đơn đặt bản dựng" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "Địa điểm nguồn" -#: build/models.py:305 +#: build/models.py:308 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:311 +#: build/models.py:314 msgid "External Build" msgstr "" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "Địa điểm đích" -#: build/models.py:322 +#: build/models.py:325 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:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "Xây dựng số lượng" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "Số kho hàng để dựng" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "Những mục hoàn thành" -#: build/models.py:335 +#: build/models.py:338 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:339 +#: build/models.py:342 msgid "Build Status" msgstr "Trnạg thái bản dựng" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "Mã trạng thái bản dựng" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "Mã lô hàng" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "Mã lô cho đầu ra bản dựng này" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "Ngày tạo" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "Ngày hoàn thành mục tiêu" -#: build/models.py:376 +#: build/models.py:379 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:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "Ngày hoàn thành" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "hoàn thành bởi" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "Cấp bởi" -#: build/models.py:399 +#: build/models.py:402 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:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Chịu trách nhiệm" -#: build/models.py:409 +#: build/models.py:420 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:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "Liên kết bên ngoài" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "Liên kết đến URL bên ngoài" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "Độ ưu tiên" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "Độ quan trọng của đơn đặt bản dựng" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "Mã dự án" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "Mã dự án cho đơn đặt bản dựng này" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:710 build/models.py:840 +#: 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:733 +#: 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:739 +#: 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:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 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:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "Không có đầu ra bản dựng đã được chỉ ra" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "Đầu ra bản dựng đã được hoàn thiện" -#: build/models.py:1019 +#: build/models.py:1030 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:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "Số lượng phải lớn hơn 0" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 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:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "Tạo mục đơn hàng" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "Dựng đối tượng" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Số lượng" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "Yêu cầu số lượng để dựng đơn đặt" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1884 +#: build/models.py:1898 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:1947 +#: build/models.py:1961 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:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "Số lượng phải là 1 cho kho sê ri" -#: build/models.py:1982 +#: build/models.py:1996 #, 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:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "Kho hàng đã bị phân bổ quá đà" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "Kho hàng" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "Kho hàng gốc" -#: build/models.py:2099 +#: build/models.py:2113 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:2108 +#: build/models.py:2122 msgid "Install into" msgstr "Cài đặt vào" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "Kho hàng đích" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "Tạo cấp" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "Tên sản phẩm" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "Đầu ra bản dựng" -#: build/serializers.py:221 +#: build/serializers.py:227 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:225 +#: build/serializers.py:231 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:229 +#: build/serializers.py:235 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:243 +#: build/serializers.py:249 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:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "Điền số lượng cho đầu ra bản dựng" -#: build/serializers.py:333 +#: build/serializers.py:339 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:339 +#: build/serializers.py:345 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:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "Số sê-ri" -#: build/serializers.py:357 +#: build/serializers.py:363 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:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "Vị trí tồn kho cho sản phẩm" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "Số sêri tự cấp" -#: build/serializers.py:380 +#: build/serializers.py:386 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:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 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:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 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:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "Vị trí kho cho đầu ra phế phẩm" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "Hủy phân bổ" -#: build/serializers.py:495 +#: build/serializers.py:501 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:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "Lý do loại bỏ đầu ra bản dựng" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "Vị trí cho đầu ra bản dựng hoàn thiện" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "Chấp nhận phân kho dang dở" -#: build/serializers.py:567 +#: build/serializers.py:573 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:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "Xử lý phân bổ kho hàng" -#: build/serializers.py:693 +#: build/serializers.py:699 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:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "Xóa toàn bộ đầu ra chưa hoàn thành" -#: build/serializers.py:700 +#: build/serializers.py:706 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:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "Chưa được cấp phép" -#: build/serializers.py:728 +#: build/serializers.py:734 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:729 +#: build/serializers.py:735 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:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "Kho quá tải" -#: build/serializers.py:759 +#: build/serializers.py:765 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:770 +#: build/serializers.py:776 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:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "Chấp nhận chưa phân bổ được" -#: build/serializers.py:777 +#: build/serializers.py:783 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:788 +#: build/serializers.py:794 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:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "Chấp nhận không hoàn thành" -#: build/serializers.py:795 +#: build/serializers.py:801 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:806 +#: build/serializers.py:812 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:818 +#: build/serializers.py:824 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:821 +#: build/serializers.py:827 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:824 +#: build/serializers.py:830 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:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "Lộ giới" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "Đầu ra bản dựng" -#: build/serializers.py:879 +#: build/serializers.py:885 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:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "Mục chi tiết bản dựng" -#: build/serializers.py:928 +#: build/serializers.py:934 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:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "Hàng hóa phải trong kho" -#: build/serializers.py:987 order/serializers.py:1583 +#: 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:993 +#: build/serializers.py:999 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:1001 +#: build/serializers.py:1007 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:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "Hàng hóa phân bổ phải được cung cấp" -#: build/serializers.py:1089 +#: build/serializers.py:1095 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:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "Ngoại trừ vị trí" -#: build/serializers.py:1099 +#: build/serializers.py:1105 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:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "Kho trao đổi" -#: build/serializers.py:1105 +#: build/serializers.py:1111 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:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "Kho thay thế" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "Cho phép phân kho sản phẩm thay thế" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "Mục tùy chọn" -#: build/serializers.py:1117 +#: build/serializers.py:1123 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:1123 +#: build/serializers.py:1129 msgid "All Items" msgstr "" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" msgstr "" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "Không thể khởi động tác vụ phân bổ tự động." - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "BOM liên quan" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "ID hàng hoá BOM" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "Tên hàng hoá BOM" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" msgstr "" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "Sản phẩm nhà cung cấp" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "Số lượng đã phân bổ" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "Tạo liên quan" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "Tên danh mục hàng hoá" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "Có thể theo dõi" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "Được kế thừa" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "Cho phép biến thể" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "Mục BOM" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "Đang sản xuất" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "Kho ngoài" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "Số hàng tồn" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "Kho hàng thay thế" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "Hàng tồn kho có sẵn" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "" @@ -1495,43 +1479,47 @@ msgstr "Chờ" msgid "Cancelled" msgstr "Đã hủy" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "Hoàn thành" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "Kho được yêu cầu cho đặt hàng bản dựng" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "Đơn đặt bản dựng quá hạn" -#: build/tasks.py:270 +#: build/tasks.py:257 #, 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:711 +#: common/api.py:722 msgid "Is Link" msgstr "Đường dẫn" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "File" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "Không có quyền xoá file đính kèm" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "Không có quyền xoá file đính kèm" @@ -1551,798 +1539,822 @@ msgstr "Mã tiền tệ không đúng" msgid "No plugin" msgstr "Không phần mở rộng" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "Nhãn mã dự án" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "Đã cập nhật" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "Nhãn thời gian của lần cập cuối cùng" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "Mã dự án duy nhất" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "Mô tả dự án" -#: common/models.py:187 +#: 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:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "Giá trị cài đặt" -#: common/models.py:836 +#: 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:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "Giá trị phải là kiểu boolean" -#: common/models.py:860 +#: 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:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "Chuỗi khóa phải duy nhất" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "Người dùng" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "Số lượng giá phá vỡ" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "Giá" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "Đơn vị giá theo số lượng cụ thể" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "Đầu mối" -#: common/models.py:1422 +#: 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:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "Tên của webhook này" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "Hoạt động" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "Webhook có hoạt động không" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "Chữ ký số" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "Chữ ký số để truy cập" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "Bí mật" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "Mã bí mật dùng chung cho HMAC" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "Mã Tin nhắn" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "Định danh duy nhất cho tin nhắn này" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "Máy chủ" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "Mãy chủ từ tin nhắn này đã được nhận" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "Đầu mục" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "Đầu mục tin nhắn" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "Thân" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "Thân tin nhắn này" -#: common/models.py:1607 +#: common/models.py:1619 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:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "Làm việc vào" -#: common/models.py:1613 +#: common/models.py:1625 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:1739 +#: common/models.py:1751 msgid "Id" msgstr "Mã" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "Tiêu đề" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Liên kết" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "Đã công bố" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "Tác giả" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "Tóm tắt" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "Đọc" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "Tin này đã được đọc?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "Tệp ảnh" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1840 +#: common/models.py:1852 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:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "Tên đơn vị" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "Biểu tượng" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "Biểu tượng đơn vị tùy chọn" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "Định nghĩa" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "Định nghĩa đơn vị" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "Đính kèm" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "Tập tin bị thiếu" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "Thiếu liên kết bên ngoài" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "Chọn file đính kèm" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "Bình luận" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "Giá trị" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "Đã tạo" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "Cập nhật lần cuối" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "Mẫu tham số" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "Tham số hộp kiểm tra không thể có đơn vị" -#: common/models.py:2449 +#: common/models.py:2559 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:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "Lựa chọn phải duy nhất" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "Tên tham số mẫu phải là duy nhất" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "Tên tham số" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "Đơn vị" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "Đơn vị vật lý cho tham số này" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "Mô tả tham số" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "Ô lựa chọn" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "Tham số này có phải là hộp kiểm tra?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "Lựa chọn" -#: common/models.py:2542 +#: common/models.py:2652 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:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "Đã bật" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "Lựa chọn sai cho giá trị tham số" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "Mẫu" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "Dữ liệu" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "Giá trị tham số" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "Ghi chú" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "Trường ghi chú tùy chọn" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "Ngữ cảnh" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "Kết quả" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "" -#: common/models.py:2961 +#: common/models.py:3071 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "Khóa" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "Mục đã nhận" @@ -2392,1235 +2404,1303 @@ msgstr "" msgid "Override" msgstr "" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "Đang chạy" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "Công việc chờ xử lý" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "Tác vụ theo lịch" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "Tác vụ thất bại" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "ID tác vụ" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "ID tác vụ duy nhất" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "Khoá" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "Thời gian khóa" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "Tên công việc" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "Chức năng" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "Tên chức năng" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "Đối số" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "Đối số công việc" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "Đối số từ khóa" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "Đối số từ khóa công việc" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "Tên tập tin" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "Không có nhóm" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "URL trang web đã bị khóa bởi cấu hình" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "Cần khởi động lại" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "Một thiết lập đã bị thay đổi yêu cầu khởi động lại máy chủ" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "Chuyển dữ liệu chờ xử lý" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "Số đợt nâng cấp cơ sở dữ liệu chờ xử lý" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "Tên thực thể máy chủ" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "Mô tả chuỗi cho thực thể máy chủ" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "Sử dụng tên thực thể" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "Sử dụng tên thực thể trên thanh tiêu đề" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "Cấm hiển thị `giới thiệu`" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "Chỉ hiển thị cửa sổ `giới thiệu` với siêu người dùng" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "Tên công ty" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "Tên công ty nội bộ" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "URL cơ sở" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "URL cơ sở cho thực thể máy chủ" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "Tiền tệ mặc định" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "Chọn tiền tệ chính khi tính giá" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "Tần suất cập nhật tiền tệ" -#: common/setting/system.py:265 +#: common/setting/system.py:278 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:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "ngày" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "Phần mở rộng cập nhật tiền tệ" -#: common/setting/system.py:272 +#: common/setting/system.py:285 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:277 -msgid "Download from URL" -msgstr "Tải về từ URL" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "Cho phép tải ảnh và tệp tin từ xa theo URL bên ngoài" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "Giới hạn kích thước tải xuống" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "Kích thước tải xuống tối đa với hình ảnh từ xa" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "User-agent được dùng để tải xuống theo URL" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "Cho phép ghi đè user-agent được dùng để tải về hình ảnh và tệp tin từ xa theo URL bên ngoài (để trống nghĩa là dùng mặc định)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "Thời gian kiểm tra bản cập nhật" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "Mức độ thường xuyên để kiểm tra bản cập nhật (điền 0 để tắt)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "Sao lưu tự động" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "Bật tính năng sao lưu tự động cơ sở dữ liệu và tệp tin đa phương tiện" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "Khoảng thời gian sao lưu tự động" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "Xác định số ngày giữa các kỳ sao lưu tự động" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "Khoảng thời gian xóa tác vụ" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "Kết quả tác vụ chạy ngầm sẽ bị xóa sau số ngày được chỉ định" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "Khoảng thời gian xóa nhật ký lỗi" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "Nhật ký lỗi sẽ bị xóa sau số ngày được chỉ định" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "Khoảng thời gian xóa thông báo" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "Thông báo sẽ bị xóa sau số ngày được chỉ định" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "Hỗ trợ mã vạch" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "Bật hỗ trợ máy quét mã vạch trong giao diện web" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "Độ trễ quét mã vạch" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "Thời gian trễ xử lý đầu đọc mã vạch" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "Hỗ trợ mã vạch qua webcam" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "Cho phép quét mã vạch qua webcam bên trong trình duyệt" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "Phiên bản Sản phẩm" -#: common/setting/system.py:407 +#: 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:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "Mẫu IPN" -#: common/setting/system.py:425 +#: common/setting/system.py:418 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:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "Cho phép trùng IPN" -#: common/setting/system.py:429 +#: common/setting/system.py:422 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:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "Cho phép sửa IPN" -#: common/setting/system.py:435 +#: common/setting/system.py:428 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:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "Sao chép dữ liệu BOM của sản phẩm" -#: common/setting/system.py:441 +#: common/setting/system.py:434 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:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "Sao chép dữ liệu tham số sản phẩm" -#: common/setting/system.py:447 +#: common/setting/system.py:440 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:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "Chép thông tin kiểm thử sản phẩm" -#: common/setting/system.py:453 +#: common/setting/system.py:446 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:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "Sao chéo mẫu tham số danh mục" -#: common/setting/system.py:459 +#: common/setting/system.py:452 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:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "Sản phẩm là mẫu bởi mặc định" -#: common/setting/system.py:471 +#: common/setting/system.py:464 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:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "Thành phần" -#: common/setting/system.py:477 +#: common/setting/system.py:470 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:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "Có thể mua" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "Sản phẩm mặc định có thể mua được" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "Có thể bán" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "Sản phẩm mặc định có thể bán được" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "Sản phẩm mặc định có thể theo dõi được" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "Ảo" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "Sản phẩm mặc định là số hóa" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "Hiển thị sản phẩm liên quan" -#: common/setting/system.py:507 +#: common/setting/system.py:500 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:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "Số liệu tồn kho ban đầu" -#: common/setting/system.py:513 +#: common/setting/system.py:506 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:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "Dữ liệu nhà cung cấp ban đầu" -#: common/setting/system.py:520 +#: common/setting/system.py:513 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:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "Định dạng tên sản phẩm hiển thị" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "Định dạng để hiển thị tên sản phẩm" -#: common/setting/system.py:533 +#: common/setting/system.py:526 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:534 +#: common/setting/system.py:527 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:539 +#: common/setting/system.py:532 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:541 +#: common/setting/system.py:534 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:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "Vị trí phần thập phân giá bán tối đa" -#: common/setting/system.py:554 +#: common/setting/system.py:547 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:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "Sử dụng giá bán nhà cung cấp" -#: common/setting/system.py:567 +#: common/setting/system.py:560 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:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "Ghi đè lịch sử mua hàng" -#: common/setting/system.py:575 +#: common/setting/system.py:568 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:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "Sử dụng giá hàng hóa trong kho" -#: common/setting/system.py:583 +#: common/setting/system.py:576 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:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "Tuổi giá kho hàng" -#: common/setting/system.py:591 +#: common/setting/system.py:584 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:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "Sử dụng giá biến thể" -#: common/setting/system.py:599 +#: common/setting/system.py:592 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:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "Chỉ các biến thể hoạt động" -#: common/setting/system.py:606 +#: common/setting/system.py:599 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:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "Tần suất tạo lại giá" -#: common/setting/system.py:621 +#: common/setting/system.py:614 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:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "Giá nội bộ" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "Bật giá nội bộ cho sản phẩm" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "Ghi đè giá nội bộ" -#: common/setting/system.py:635 +#: common/setting/system.py:628 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:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "Bật in tem nhãn" -#: common/setting/system.py:642 +#: common/setting/system.py:643 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:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "DPI hỉnh ảnh tem nhãn" -#: common/setting/system.py:649 +#: common/setting/system.py:650 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:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "Bật báo cáo" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "Cho phép tạo báo cáo" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "Chế độ gỡ lỗi" -#: common/setting/system.py:662 +#: common/setting/system.py:663 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:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "Khổ giấy" -#: common/setting/system.py:674 +#: common/setting/system.py:675 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:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "Bắt buộc đơn vị tham số" -#: common/setting/system.py:681 +#: common/setting/system.py:682 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:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "Sê ri toàn cục duy nhất" -#: common/setting/system.py:688 +#: common/setting/system.py:689 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:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "Xóa kho đã hết hàng" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "Mẫu sinh mã theo lô" -#: common/setting/system.py:700 +#: common/setting/system.py:713 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:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "Quá hạn trong kho" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "Bật chức năng quá hạn tồn kho" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "Bán kho quá hạn" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "Cho phép bán hàng kho quá hạn" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "Thời gian hàng cũ trong kho" -#: common/setting/system.py:718 +#: common/setting/system.py:731 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:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "Dựng kho quá hạn" -#: common/setting/system.py:726 +#: common/setting/system.py:739 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:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "Kiểm soát sở hữu kho" -#: common/setting/system.py:732 +#: common/setting/system.py:745 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:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "Biểu tượng địa điểm kho mặc định" -#: common/setting/system.py:738 +#: common/setting/system.py:751 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:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "Hiển thị hàng hóa đã lắp đặt" -#: common/setting/system.py:744 +#: common/setting/system.py:757 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:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "Mã tham chiếu đơn đặt bản dựng" -#: common/setting/system.py:766 +#: common/setting/system.py:779 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:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "Bật đơn hàng trả lại" -#: common/setting/system.py:818 +#: common/setting/system.py:839 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:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "Mẫu tham chiếu đơn hàng trả lại" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "Sửa đơn hàng trả lại đã hoàn thành" -#: common/setting/system.py:839 +#: common/setting/system.py:860 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:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "Mẫu tham chiếu đơn đặt hàng" -#: common/setting/system.py:846 +#: common/setting/system.py:867 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:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "Vận chuyển mặc định đơn đặt hàng" -#: common/setting/system.py:858 +#: common/setting/system.py:879 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:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "Sửa đơn đặt hàng đã hoàn thành" -#: common/setting/system.py:865 +#: common/setting/system.py:886 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:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:887 -msgid "Purchase Order Reference Pattern" -msgstr "Mẫu tham chiếu đơn đặt mua" - -#: common/setting/system.py:889 -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:901 -msgid "Edit Completed Purchase Orders" -msgstr "Sửa đơn đặt mua đã hoàn thành" - -#: common/setting/system.py:903 -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:909 -msgid "Convert Currency" +#: common/setting/system.py:908 +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 "Mẫu tham chiếu đơn đặt mua" + +#: common/setting/system.py:918 +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 +msgid "Edit Completed Purchase Orders" +msgstr "Sửa đơn đặt mua đã hoàn thành" + +#: common/setting/system.py:932 +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 +msgid "Convert Currency" +msgstr "" + +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "Tự động hoàn thành đơn đặt mua" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "Bật quên mật khẩu" -#: common/setting/system.py:925 +#: 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:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "Bật đăng ký" -#: common/setting/system.py:931 +#: 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:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "Bật SSO" -#: common/setting/system.py:937 +#: 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:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "Bật đăng ký SSO" -#: common/setting/system.py:944 +#: 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:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:974 +#: 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 "" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "Yêu cầu email" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 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:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "Người dùng tự động điền SSO" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 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:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "Thư 2 lần" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 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:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "Mật khẩu 2 lần" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 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:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "Các tên miền được phép" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 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:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "Nhóm khi đăng ký" -#: common/setting/system.py:1014 +#: 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." msgstr "" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "Bắt buộc MFA" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 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:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "Kiểm tra phần mở rộng khi khởi động" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 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:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "Kiểm tra cập nhật plugin" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "Bật tích hợp URL" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 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:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "Bật tích hợp điều hướng" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 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:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "Bật tích hợp ứng dụng" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "Bật phần mở rộng để thêm ứng dụng" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "Cho phép tích hợp lập lịch" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 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:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "Bật tích hợp nguồn cấp sự kiện" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 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:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "Ngoại trừ vị trí bên ngoài" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "Giai đoạn kiểm kê tự động" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "Hiển thị tên đầy đủ của người dùng" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 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:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3905,21 +3985,37 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "Nhận báo cáo lỗi" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "Nhận thông báo khi có lỗi hệ thống" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" msgstr "" @@ -3965,365 +4061,369 @@ msgstr "" msgid "Manufacturer is Active" msgstr "" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "Nhà sản xuất" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "Doanh nghiêp" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "Doanh nghiệp" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "Mô tả công ty" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "Mô tả của công ty" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "Trang web" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "URL trang web của công ty" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "Số điện thoại" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "Số điện thoại liên hệ" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "Địa chỉ email liên hệ" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "Liên hệ" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "Đầu mối liên hệ" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "Liên kết đến thông tin công ty ngoài" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "Bạn có bán hàng cho công ty này?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "Bạn có mua hàng từ công ty này?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "Công ty này có sản xuất sản phẩm?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "Tiền tệ mặc định dùng cho công ty này" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "Địa chỉ" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "Địa chỉ" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "Chọn doanh nghiệp" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "Tiêu đề địa chỉ" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "Tiêu đề mô tả mục địa chỉ" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "Địa chỉ chính" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "Đặt làm địa chỉ chính" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "Dòng 1" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "Địa chỉ dòng 1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "Dòng 2" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "Địa chỉ dòng 2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "Mã bưu chính" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "Thành phố/Vùng" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "Mã bưu chính thành phố/vùng" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "Bang/Tỉnh" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "Bang hay tỉnh" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "Quốc gia" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "Địa chỉ quốc gia" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "Ghi chú vận chuyển" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "Ghi chú dành cho chuyển phát nhanh" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "Ghi chú nội bọ chuyển phát nhanh" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "Ghi chú nội bộ sử dụng cho chuyển phát nhanh" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "Liên kết thông tin địa chỉ (bên ngoài)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "Sản phẩm nhà sản xuất" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "Sản phẩm cơ bản" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "Chọn sản phẩm" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "Chọn nhà sản xuất" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "Mã số nhà sản xuất" -#: company/models.py:545 +#: company/models.py:550 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:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "Mô tả sản phẩm của nhà sản xuất" -#: company/models.py:686 +#: company/models.py:691 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:693 +#: company/models.py:698 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:707 +#: company/models.py:712 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:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Nhà cung cấp" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "Chọn nhà cung cấp" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "Đơn vị quản lý kho nhà cung cấp" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" msgstr "" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "Chọn sản phẩm của nhà sản xuất" -#: company/models.py:805 +#: company/models.py:810 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:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "Mô tả sản phẩm nhà cung cấp" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "chi phí cơ sở" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "Thu phí tối thiểu (vd: phí kho bãi)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "Đóng gói" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "Đóng gói sản phẩm" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "Số lượng gói" -#: company/models.py:846 +#: company/models.py:851 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:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "nhiều" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "Đặt hàng nhiều" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "Số lượng có sẵn từ nhà cung cấp" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "Sẵn hàng đã được cập nhật" -#: company/models.py:885 +#: company/models.py:890 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:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:191 +#: company/serializers.py:185 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:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "Còn hàng" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "" @@ -4428,67 +4528,67 @@ msgstr "" msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "Hợp lệ" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "" @@ -4588,7 +4688,7 @@ msgstr "" msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "Không rõ" @@ -4692,7 +4792,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "Nhóm" @@ -4720,7 +4820,7 @@ msgstr "" msgid "Order Reference" msgstr "Tham chiếu đơn đặt" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "" @@ -4728,7 +4828,7 @@ msgstr "" msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "Tạo bởi" @@ -4764,57 +4864,69 @@ msgstr "" msgid "Target Date After" msgstr "" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "" + +#: order/api.py:236 +msgid "Updated After" +msgstr "" + +#: order/api.py:287 msgid "Has Pricing" msgstr "" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "Đặt hàng" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "Sản phẩm nội bộ" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "Đã hoàn thành" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Đơn hàng" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "Đơn hàng" msgid "Sales Order" msgstr "Đơn đặt hàng" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "Tổng tiền" msgid "Total price for this order" msgstr "Tổng tiền cho đơn hàng hàng" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "Tiền tệ đơn đặt hàng" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 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)" @@ -4851,718 +4963,750 @@ msgstr "Tiền tệ cho đơn đặt này (để trống để sử dụng tiề msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:378 +#: order/models.py:380 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:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "Mô tả đơn đặt (tùy chọn)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "Mã dự án đã chọn cho đơn đặt hàng này" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "Liên kết đến trang bên ngoài" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Ngày mục tiêu" -#: order/models.py:477 +#: order/models.py:479 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:497 +#: order/models.py:499 msgid "Issue Date" msgstr "Ngày phát hành" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "Ngày đặt hàng đã phát hành" #: order/models.py:506 +msgid "Updated At" +msgstr "" + +#: order/models.py:515 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:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "Đầu mối liên hệ của đơn đặt này" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "Địa chỉ công ty cho đơn đặt này" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "Mã đặt hàng" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "Trạng thái" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "Trạng thái đơn đặt mua" -#: order/models.py:643 +#: order/models.py:667 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:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "Tham chiếu nhà cung cấp" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "Mã tham chiếu đơn đặt nhà cung cấp" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "nhận bởi" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "Ngày đặt hàng đã được hoàn thiện" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "Đích đến" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "" -#: order/models.py:727 +#: order/models.py:751 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:997 +#: order/models.py:1021 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:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "Số lượng phải là số dương" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Khách hàng" -#: order/models.py:1327 +#: order/models.py:1367 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:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "Tham chiếu khách hàng " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "Mã tham chiếu đơn đặt của khách hàng" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "Ngày giao hàng" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "vận chuyển bằng" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1423 +#: order/models.py:1463 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:1427 +#: order/models.py:1467 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:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1441 +#: order/models.py:1481 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:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "Số lượng mặt hàng" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "" + +#: order/models.py:1839 msgid "Line item reference" msgstr "Tham chiếu khoản riêng" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "Ghi chú khoản riêng" -#: order/models.py:1799 +#: order/models.py:1861 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:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "Mô tả khoản riêng (tùy chọn)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "Ngữ cảnh bổ sung" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "Đơn giá" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1892 +#: order/models.py:1956 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:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1945 +#: order/models.py:1987 +msgid "An external build order is required for assembly parts" +msgstr "" + +#: order/models.py:2023 msgid "Supplier part" msgstr "Sản phẩm nhà cung cấp" -#: order/models.py:1952 +#: order/models.py:2030 msgid "Received" msgstr "Đã nhận" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "Số mục đã nhận" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "Giá mua" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "Giá đơn vị mua" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2094 +#: order/models.py:2174 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:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "Giá bán" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "Giá bán đơn vị" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "Đã chuyển" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "Số lượng đã vận chuyển" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "Ngày vận chuyển" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "Ngày giao hàng" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "Ngày giao hàng của vận chuyển" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "Kiểm tra bởi" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "Người dùng đã kiểm tra vận chuyển này" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Vận chuyển" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "Mã vận chuyển" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "Số theo dõi" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "Thông tin theo dõi vận chuyển" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "Mã hóa đơn" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "Số tham chiếu liên kết với hóa đơn" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "Vận đơn đã được gửi đi" -#: order/models.py:2382 +#: order/models.py:2470 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:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "Hàng trong kho chưa được giao" -#: order/models.py:2529 +#: order/models.py:2608 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:2532 +#: order/models.py:2611 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:2535 +#: order/models.py:2614 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:2551 +#: order/models.py:2630 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:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 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:2557 +#: order/models.py:2636 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:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 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:2566 +#: order/models.py:2645 msgid "Line" msgstr "Dòng" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "Tham chiếu vận đơn của đơn hàng bán" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "Hàng hóa" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "Chọn hàng trong kho để phân bổ" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "Nhập số lượng phân kho" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "Tham chiếu đơn hàng trả lại" -#: order/models.py:2727 +#: order/models.py:2808 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:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "Trạng thái đơn hàng trả lại" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3015 +#: order/models.py:3096 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:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "Ngày nhận được" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "Kết quả" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "Kết quả cho hàng hóa dòng này" -#: order/models.py:3051 +#: order/models.py:3132 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:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "" -#: order/serializers.py:110 +#: 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" +msgstr "" + +#: order/serializers.py:112 #: 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 msgid "Line Items" msgstr "Mục dòng" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "Tên nhà cung cấp" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "Đơn đặt không thể bị hủy" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 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:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 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:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "Đơn đặt là không được mở" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "Tiền tệ giá mua" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "Mã sản phẩm nội bộ" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "Sản phẩm nhà cung cấp phải được chỉ định" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "Đơn đặt mua phải được chỉ định" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "Nhà cung cấp phải phù hợp với đơn đặt mua" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "Đơn đặt mua phải phù hợp với nhà cung cấp" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "Mục dòng" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "Chọn vị trí đích cho hàng hóa đã nhận" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "Nhập mã lô cho hàng trong kho đang đến" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "Ngày hết hạn" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "Nhập số sê ri cho hàng trong kho đang đến" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "Mã vạch" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "Mã vạch đã quét" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "Mã vạch đã được dùng" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "Dòng hàng hóa phải được cung cấp" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "Vị trí đích phải được chỉ ra" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "Giá trị mã vạch đã cung cấp phải duy nhất" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "Vận đơn đã hoàn thành" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "Tiền tệ giá bán" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "Chưa cung cấp thông tin vận chuyển" -#: order/serializers.py:1541 order/serializers.py:1687 +#: 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:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "Số lượng phải là số dương" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "Nhập số sê ri để phân bổ" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "Vận đơn đã được chuyển đi" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 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:1777 +#: 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:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "Dòng riêng biệt đơn hàng trả lại" -#: order/serializers.py:2016 +#: order/serializers.py:2136 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:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "Line item đã nhận được" -#: order/serializers.py:2056 +#: order/serializers.py:2176 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:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "Tiền tệ giá đồng hạng" @@ -5598,146 +5742,150 @@ msgstr "Hoàn tiền" msgid "Reject" msgstr "Từ chối" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "Đơn đặt mua quá hạn" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Đơn đặt mua {po} quá hạn" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "Đơn bán hàng quá hạn" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Đơn bán hàng {so} đã quá hạn" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" msgstr "" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" msgstr "" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" msgstr "" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" msgstr "" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" msgstr "" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "" @@ -5746,11 +5894,11 @@ msgstr "" msgid "Part Category" msgstr "Danh mục sản phẩm" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "Danh mục sản phẩm" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "Điểm bán mặc định" @@ -5778,7 +5926,7 @@ msgstr "Từ khóa mặc định cho sản phẩm trong danh mục này" msgid "Icon" msgstr "Biểu tượng" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "Biểu tượng (tùy chọn)" @@ -5799,1025 +5947,1050 @@ msgstr "Giá trị mặc định" msgid "Default Parameter Value" msgstr "Giá trị tham số mặc định" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "Nguyên liệu" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, 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:701 +#: part/models.py:702 #, 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:768 +#: part/models.py:769 #, 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:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:907 +#: part/models.py:902 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:1037 +#: part/models.py:1032 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:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1060 +#: part/models.py:1055 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:1075 +#: part/models.py:1070 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:1107 +#: part/models.py:1102 msgid "Part name" msgstr "Tên sản phẩm" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "Là Mẫu" -#: part/models.py:1113 +#: part/models.py:1108 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:1123 +#: part/models.py:1118 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:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "Biến thể của" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "Mô tả (không bắt buộc)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "Từ khóa" -#: part/models.py:1139 +#: part/models.py:1134 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:1149 +#: part/models.py:1144 msgid "Part category" msgstr "Danh mục sản phẩm" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1164 +#: part/models.py:1159 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:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "Phiên bản" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "Hàng hóa này sẽ được cất vào đâu?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "Hết hạn mặc định" -#: part/models.py:1229 +#: part/models.py:1224 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:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "Kho tối thiểu" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "Cấp độ kho tối thiểu được phép" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "Đơn vị đo cho sản phẩm này" -#: part/models.py:1254 +#: part/models.py:1258 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:1260 +#: part/models.py:1264 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:1266 +#: part/models.py:1270 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:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1278 +#: part/models.py:1282 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:1284 +#: part/models.py:1288 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:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "Sản phẩm này đang hoạt động?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1300 +#: part/models.py:1304 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:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "Giá trị tổng kiểm BOM" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "Giá trị tổng kiểm BOM đã được lưu" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "BOM kiểm tra bởi" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "Ngày kiểm tra BOM" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "Tạo người dùng" -#: part/models.py:1352 +#: part/models.py:1356 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:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "Bán nhiều" -#: part/models.py:3313 +#: part/models.py:3327 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:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "Chi phí BOM tối thiểu" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "Chi phí thành phần sản phẩm tối thiểu" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "Chi phí BOM tối đa" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "Chi phí thành phần sản phẩm tối đa" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "Chi phí mua vào tối thiểu" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "Chi phí mua vào tối thiểu trong lịch sử" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "Chi phí mua tối đa" -#: part/models.py:3351 +#: part/models.py:3365 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:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "Giá nội bộ tối thiểu" -#: part/models.py:3358 +#: part/models.py:3372 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:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "Giá nội bộ tối đa" -#: part/models.py:3365 +#: part/models.py:3379 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:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "Giá nhà cung ứng tối thiểu" -#: part/models.py:3372 +#: part/models.py:3386 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:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "Giá nhà cung ứng tối đa" -#: part/models.py:3379 +#: part/models.py:3393 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:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "Giá trị biến thể tối thiểu" -#: part/models.py:3386 +#: part/models.py:3400 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:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "Chi phí biến thể tối đa" -#: part/models.py:3393 +#: part/models.py:3407 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:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "Chi phí tối thiểu" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "Ghi đề chi phí tối thiểu" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "Chi phí tối đa" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "Ghi đề chi phí tối đa" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "Chi phí tối thiểu tính toán tổng thể" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "Chi phí tối đa tính toán tổng thể" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "Giá bán thấp nhất" -#: part/models.py:3428 +#: part/models.py:3442 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:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "Giá bán cao nhất" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "Giá bán cao nhất dựa trên phá giá" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "Chi phí bán hàng tối thiểu" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "Giá bán hàng tối thiểu trong lịch sử" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "Giá bán hàng tối đa" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "Giá bán hàng tối đa trong lịch sử" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "Sản phẩm dành cho kiểm kê" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "Tổng số hàng" -#: part/models.py:3473 +#: part/models.py:3487 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:3481 +#: part/models.py:3495 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:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "Ngày" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "Kiểm kê đã thực hiện" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "Chi phí kho tối thiểu" -#: part/models.py:3494 +#: part/models.py:3508 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:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "Chi phí kho tối đa" -#: part/models.py:3501 +#: part/models.py:3515 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:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "Tên kiểm thử" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "Nhập tên cho kiểm thử" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "Mô tả kiểm thử" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "Nhập mô tả cho kiểm thử này" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "Bắt buộc" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "Kiểm thử này bắt buộc phải đạt?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "Giá trị bắt buộc" -#: part/models.py:3746 +#: part/models.py:3760 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:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "Yêu cầu đính kèm" -#: part/models.py:3753 +#: part/models.py:3767 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:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "Chọn sản phẩm cha" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "Sản phẩm phụ" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "Chọn sản phẩm được dùng trong BOM" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "Số lượng BOM cho mục BOM này" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "Mục BOM này là tùy chọn" -#: part/models.py:4005 +#: part/models.py:4082 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:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "Tham chiếu mục BOM" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "Ghi chú mục BOM" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "Giá trị tổng kiểm" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "Giá trị tổng kiểm dòng BOM" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "Đã xác minh" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "Mục BOM này là hợp lệ" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "Nhận thừa hưởng" -#: part/models.py:4072 +#: part/models.py:4149 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:4078 +#: part/models.py:4155 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:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 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:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "Sản phẩm phụ phải được chỉ định" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "Sảm phẩm thay thế mục BOM" -#: part/models.py:4369 +#: part/models.py:4446 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:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "Hàng hóa BOM cha" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "Sản phẩm thay thế" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "Sản phẩm 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "Sản phẩm 2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "Chọn sản phẩm liên quan" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "" -#: part/models.py:4441 +#: part/models.py:4518 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:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "Đã tồn tại mối quan hệ trùng lặp" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "Phụ mục" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 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:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "Sản phẩm gốc" -#: part/serializers.py:384 +#: 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:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "Sao chép ảnh" -#: part/serializers.py:390 +#: 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:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "Sao chép BOM" -#: part/serializers.py:397 +#: 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:403 -msgid "Copy Parameters" -msgstr "Sao chép thông số" - -#: part/serializers.py:404 +#: 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:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "Sao chép ghi chú" -#: part/serializers.py:411 +#: 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:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "Số liệu tồn kho ban đầu" -#: part/serializers.py:438 +#: part/serializers.py:449 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:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "Vị trí kho ban đầu" -#: part/serializers.py:446 +#: part/serializers.py:457 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:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "Chọn nhà cung cấp (hoặc để trống để bỏ qua)" -#: part/serializers.py:479 +#: part/serializers.py:490 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:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "Mã số nhà sản xuất" -#: part/serializers.py:496 +#: part/serializers.py:507 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:505 +#: part/serializers.py:516 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:516 +#: part/serializers.py:527 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:523 +#: part/serializers.py:534 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:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "Tên danh mục" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "Đang dựng" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "Hàng trong kho" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: 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:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "Nhân bản sản phẩm" -#: part/serializers.py:924 +#: part/serializers.py:970 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:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "Số liệu kho ban đầu" -#: part/serializers.py:931 +#: part/serializers.py:977 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:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "Thông tin nhà cung cấp" -#: part/serializers.py:938 +#: part/serializers.py:984 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:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "Sao chép thông số nhóm hàng" -#: part/serializers.py:948 +#: part/serializers.py:994 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:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "Ảnh hiện có" -#: part/serializers.py:954 +#: part/serializers.py:1000 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:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "Tệp hình ảnh không tồn tại" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "Xác minh toàn bộ hóa đơn vật liệu" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "Có thể dựng" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" msgstr "" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" msgstr "" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" msgstr "" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "Giá thấp nhất" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "Giá trị tính toán ghi đè cho giá tối thiểu" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "Tiền tế giá tối thiểu" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "Giá cao nhất" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "Giá trị tính toán ghi đè cho giá tối đa" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "Tiền tế giá tối đa" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "Cập nhật" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "Cập nhật giá cho sản phẩm này" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, 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:1510 +#: part/serializers.py:1549 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:1513 +#: part/serializers.py:1552 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:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 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:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "Xóa dữ liệu đã tồn tại" -#: part/serializers.py:1906 +#: part/serializers.py:1998 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:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "Bao gồm thừa hưởng" -#: part/serializers.py:1912 +#: part/serializers.py:2004 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:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "Bỏ qua dòng không hợp lệ" -#: part/serializers.py:1918 +#: part/serializers.py:2010 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:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "Sao chép sản phẩm thay thế" -#: part/serializers.py:1924 +#: part/serializers.py:2016 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:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "Thông báo sắp hết hàng" -#: part/tasks.py:43 +#: part/tasks.py:44 #, 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:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7031,15 +7204,15 @@ msgstr "Số lượng cần phân bổ" msgid "Label printing failed" msgstr "In nhãn thất bại" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "" @@ -7100,7 +7273,7 @@ msgstr "Cung cấp hỗ trợ gốc cho mã vạch" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7446,20 +7619,20 @@ msgstr "" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "Máy in nhãn InvenTree PDF" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 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:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Chế độ gỡ lỗi" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 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" @@ -7500,7 +7673,7 @@ msgstr "Viền" 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:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "Ngang" @@ -7580,64 +7753,77 @@ 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:320 -msgid "Only staff users can administer plugins" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" msgstr "" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "Cài đặt phần mở rộng thành công" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Cài đặt phần bổ sung đến {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:337 -msgid "Plugin uninstalling is disabled" -msgstr "" - -#: plugin/installer.py:341 -msgid "Plugin cannot be uninstalled as it is currently active" +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" msgstr "" #: plugin/installer.py:347 -msgid "Plugin cannot be uninstalled as it is mandatory" +msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:352 -msgid "Plugin cannot be uninstalled as it is a sample plugin" +#: plugin/installer.py:351 +msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" #: plugin/installer.py:357 +msgid "Plugin cannot be uninstalled as it is mandatory" +msgstr "" + +#: plugin/installer.py:362 +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 "" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "" @@ -7689,21 +7875,21 @@ msgstr "" msgid "Plugin" msgstr "Phần bổ sung" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "Không tìm thấy tác giả" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, 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:784 +#: plugin/registry.py:789 #, 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:786 +#: plugin/registry.py:791 #, 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}" @@ -7884,55 +8070,55 @@ msgstr "Cài đặt chưa được xác nhận" msgid "Either packagename or URL must be provided" msgstr "" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "Tải lại đầy đủ" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "Buộc tải lại" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "Kích hoạt phần bổ sung" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "Kích hoạt phần bổ sung này" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "" @@ -7948,7 +8134,7 @@ msgstr "" msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "" @@ -7972,152 +8158,156 @@ msgstr "Thư" msgid "Template file with this name already exists" msgstr "" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "Tên mẫu" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "Mẫu tên tệp" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "Bộ lọc" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "Khổ giấy cho báo cáo PDF" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "Tạo báo cáo theo hướng ngang" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "Chiều rộng [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "Chiều rộng nhãn, tính theo mm" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "Chiều cao [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "Chiều cao nhãn, tính theo mm" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "Mẫu trích" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "Tệp báo cáo mẫu" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "Mô tả tệp báo cáo mẫu" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "Tài sản" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "Tệp báo cáo tài sản" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "Mô tả tệp báo cáo tài sản" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "" + +#: report/serializers.py:118 msgid "Select report template" msgstr "" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Số sê-ri" @@ -8215,7 +8405,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:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "Mục đã cài đặt" @@ -8248,184 +8438,196 @@ 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:169 -msgid "Asset file does not exist" -msgstr "Tệp tin tài sản không tồn tại" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "Không tìm thấy tệp hình ảnh" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "" + +#: report/templatetags/report.py:455 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:384 +#: report/templatetags/report.py:553 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:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "Mã trạng thái" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "Địa điểm bên ngoài" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "Cây sản phẩm" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "Ngày hết hạn trước đó" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "Ngày hết hạn sau đó" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "Ế" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "Bắt buộc nhập số lượng" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "Phải cung cấp sản phẩm hợp lệ" -#: stock/api.py:1120 +#: stock/api.py:1123 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:1130 +#: stock/api.py:1133 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:1162 +#: stock/api.py:1165 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:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" msgstr "" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" msgstr "" @@ -8441,19 +8643,19 @@ msgstr "Loại vị trí kho hàng" 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:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "Kho hàng" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "Vị trí kho hàng" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "Chủ sở hữu" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "Chọn chủ sở hữu" @@ -8461,7 +8663,7 @@ msgstr "Chọn chủ sở hữu" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "Bên ngoài" @@ -8481,274 +8683,282 @@ msgstr "Loại vị trí kho hàng của địa điểm này" 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:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "" -#: stock/models.py:909 +#: stock/models.py:924 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:936 stock/serializers.py:455 +#: stock/models.py:945 +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 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:953 +#: stock/models.py:979 #, 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:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 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:966 +#: stock/models.py:992 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:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "Hàng hóa không thể thuộc về chính nó" -#: stock/models.py:993 +#: stock/models.py:1019 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:1006 +#: stock/models.py:1032 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:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "Hàng trong kho cha" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "Sản phẩm cơ bản" -#: stock/models.py:1042 +#: stock/models.py:1068 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:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "Hàng trong kho này được đặt ở đâu?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 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:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "Đã cài đặt trong" -#: stock/models.py:1073 +#: stock/models.py:1099 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:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "Số sê ri cho mục này" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "Mã lô cho hàng trong kho này" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "Số lượng tồn kho" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "Bản dựng nguồn" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "Bản dựng cho hàng hóa này" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "Tiêu thụ bởi" -#: stock/models.py:1137 +#: stock/models.py:1163 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:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "Đơn đặt mua nguồn" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "Đơn đặt mua cho hàng hóa này" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "Đơn hàng bán đích" -#: stock/models.py:1167 +#: stock/models.py:1193 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:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "Xóa khi thiếu hụt" -#: stock/models.py:1186 +#: stock/models.py:1212 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:1207 +#: stock/models.py:1233 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:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "Đã chuyển đổi sang sản phẩm" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1891 +#: stock/models.py:1917 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:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "Số lượng phải là số nguyên" -#: stock/models.py:1905 +#: stock/models.py:1931 #, 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:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "Số lượng không khớp với số sêri" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2069 +#: stock/models.py:2095 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:2073 +#: stock/models.py:2099 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:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "Hàng trong kho chứa hàng hóa khác" -#: stock/models.py:2079 +#: stock/models.py:2105 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:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "Hàng trong kho hiện đang sản xuất" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "Không thể hợp nhất kho nối tiếp" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "Mặt hàng trùng lặp" -#: stock/models.py:2096 +#: stock/models.py:2122 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:2104 +#: stock/models.py:2130 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:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "Mã trạng thái kho phải phù hợp" -#: stock/models.py:2409 +#: stock/models.py:2435 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:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "Ghi chú đầu vào" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3024 +#: stock/models.py:3050 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:3028 +#: stock/models.py:3054 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:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "Kết quả kiểm thử" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "Giá trị đầu ra kiểm thử" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "Đính kèm kết quả kiểm thử" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "Ghi chú kiểm thử" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "" @@ -8792,246 +9002,246 @@ msgstr "" msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "Mục cha" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:440 +#: stock/serializers.py:454 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:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "Điền số sêri cho hàng hóa mới" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "Số hiệu hàng hoá nhà cung cấp" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "Đã hết hạn" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "Mục con" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:643 +#: stock/serializers.py:668 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:681 +#: stock/serializers.py:706 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:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, 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:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "Vị trí kho đích" -#: stock/serializers.py:735 +#: stock/serializers.py:760 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:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "Số sêri đã tồn tại" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "Chọn mặt hàng để lắp đặt" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "Số lượng để cài đặt" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "Nhập số lượng hàng hóa để cài đặt" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "Thêm ghi chú giao dịch (tùy chọn)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 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:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "Mặt hàng không khả dụng" -#: stock/serializers.py:845 +#: stock/serializers.py:870 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:858 +#: stock/serializers.py:883 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:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "Vị trí đích cho hàng hóa bị gỡ bỏ" -#: stock/serializers.py:931 +#: 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:944 +#: 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:961 +#: 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:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "Mã trạng thái mặt hàng" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "Chọn mặt hàng để đổi trạng thái" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "Không có mặt hàng nào được chọn" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "Kho phụ" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "Sản phẩm phải có thể bán được" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 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:1330 +#: stock/serializers.py:1374 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:1354 +#: stock/serializers.py:1398 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:1360 +#: stock/serializers.py:1404 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:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "Ghi chú phân bổ kho" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 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:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "Ghi chú gộp kho" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "Cho phép nhiều nhà cung không khớp" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 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:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "Cho phép trạng thái không khớp" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 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:1479 +#: stock/serializers.py:1523 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:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "Giá trị khóa chính mặt hàng" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "Ghi chú giao dịch kho" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "" @@ -9369,227 +9579,247 @@ msgstr "Lần cuối mã thông báo được sử dụng" msgid "Revoked" msgstr "Đã thu hồi" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "Quyền hạn đã đặt" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "Xem" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "Quyền để xem mục" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "Thêm" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "Quyền để thêm mục" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "Đổi" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "Quyển để sửa mục" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "Xóa" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "Quyền để xóa mục" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "Quản trị" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "Đơn mua hàng" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "Đơn hàng bán" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "Đơn hàng trả lại" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "Tên người dùng" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "Tên" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "Họ người dùng" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "Họ" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "Tên người dùng" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "Địa chỉ email của người dùng" -#: users/serializers.py:309 -msgid "Staff" -msgstr "Nhân viên" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "Người dùng có quyền nhân viên" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "Superuser" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "Người dùng này là superuser" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "Tài khoản người dùng đang hoạt động" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "Tài khoản của bạn đã được tạo." -#: users/serializers.py:446 +#: users/serializers.py:491 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:452 +#: users/serializers.py:497 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 274c9fe672..e0f83e84cb 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 20:21\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "未找到 API 端点" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "批量操作必须提供物品或过滤器列表" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "批量操作必须提供物料清单" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "必须以列表形式提供项目" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "提供了无效的单位" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "必须以字典形式提供筛选器" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "提供了无效的过滤器" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "所有过滤器只能使用true" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "没有符合所供条件的项目" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "未提供数据" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." msgstr "此字段的值必须是唯一的。" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "用户没有权限查阅当前模型。" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "不能将 {original} 转换到 {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "提供的数量无效" @@ -112,13 +105,13 @@ msgstr "输入日期" msgid "Invalid decimal value" msgstr "无效的数值" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "备注" @@ -131,75 +124,91 @@ msgstr "值' {name}' 未出现在模式格式中" msgid "Provided value does not match required pattern: " msgstr "提供的值与所需模式不匹配:" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "无法一次序列化超过 1000 个项目" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "序列号为空白" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "重复的序列号" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "无效群组: {group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "组范围 {group} 超出了允许的数量 ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "未找到序列号" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "唯一序列号 ({n}) 必须匹配数量 ({q})" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "从这个值中删除 HTML 标签" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "数据包含禁止的 markdown 内容" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "无效URL:没有主机名" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "无效URL:无法解析的主机名" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "URL指向私有或保留IP地址" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "太多重定向" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "连接错误" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "服务器响应状态码无效" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "发生异常" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "服务器响应的内容长度值无效" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "图片尺寸过大" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "图片下载超出最大尺寸" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "远程服务器返回了空响应" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "提供的 URL 不是一个有效的图片文件" @@ -207,11 +216,11 @@ msgstr "提供的 URL 不是一个有效的图片文件" msgid "Log in to the app" msgstr "登录应用程序" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "电子邮件" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "您必须启用双重身份验证才能进行后续操作。" @@ -255,133 +264,108 @@ msgstr "参考字段必须符合指定格式" msgid "Reference number is too large" msgstr "参考编号过大" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "无效选项" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "名称" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "描述" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "描述(选填)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "路径" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "同一父级下不能存在重复名称" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown备注(选填)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "条码数据" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "第三方条码数据" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "条码哈希值" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "条码数据的唯一哈希值" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "检测到已存在条码" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "任务失败" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "后台工作任务“{f}”在 {n} 次尝试后失败" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "服务器错误" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "服务器记录了一个错误。" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "必须是有效数字" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "货币" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "从可用选项中选择货币" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." msgstr "此字段不能为空。" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "无效值" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "远程图片" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "远程图片文件的 URL" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "未启用从远程 URL下载图片" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "从远程URL下载图像失败" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" msgstr "无效的内容类型格式" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" msgstr "未找到内容类型" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" msgstr "内容类型不匹配所需的 mixin 类" @@ -537,11 +521,11 @@ msgstr "中文 (简体)" msgid "Chinese (Traditional)" msgstr "中文 (繁体)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "有可用更新" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "InvenTree有可用更新" @@ -553,30 +537,30 @@ msgstr "无效的物理单位" msgid "Not a valid currency code" msgstr "无效的货币代码" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "订单状态" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "父级生产订单" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "包含变体" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "包含变体" msgid "Part" msgstr "零件" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "类别" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "可测试部分" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "分配给我" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "负责人" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "创建时间早于" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "创建时间晚于" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "有开始日期" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "开始日期早于" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "开始日期晚于" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "有目标日期" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "目标日期早于" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "目标日期晚于" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "完成日期早于" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "完成日期晚于" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "最小日期" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "最大日期" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "排除树" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "生产订单必须取消后才能删除" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "耗材" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "可选项" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "装配件" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "可追溯" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "需检测" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "未结算订单" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "已分配" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "已消耗" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "已订购" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "未找到版本" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "生产订单" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "库存位置" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" msgstr "产出" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "按产出库存项ID筛选,使用“null”查找未安装的生产项。" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "生产订单" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "装配物料清单尚未验证" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "无法为未激活的零件创建生产订单" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "无法为已解锁的零件创建生产订单" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "生产订单仅能通过外部采购可购买零件来完成" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "必须指定负责的用户或组" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "生产订单关联零件不可变更" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "目标日期必须在开始日期之后" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "生产订单编号" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "生产订单编号" msgid "Reference" msgstr "编号" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "生产订单的简要说明(可选)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" msgstr "该生产订单所属的上级生产订单" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "选择要生产的零件" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "销售订单编号" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" msgstr "该生产订单关联的销售订单" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "源库位" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "指定本次生产领料的来源库位(留空可从任意库位调拨)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "外协生产" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "该生产订单由外部供应商完成" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "目标库位" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "选择生产完成品的存放库位" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "生产数量" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "需要生产的库存品数量" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "已完成项目" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "已完成并入库的库存物品数量" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "生产状态" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "生产状态代码" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "批号" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "本批产出的批次编号" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "建立日期" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "生产开始日期" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "此生产订单的计划开始日期" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "计划完成日期" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "生产订单的计划完成时间,逾期后系统将标记为超期。" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "完成日期" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "完成人" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "发起人" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "创建该生产订单的用户" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "责任方" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "该生产订单的责任人或责任团队" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "外部链接" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "指向外部资源的URL链接" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "生产优先级" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "此生产订单的优先级" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "项目编号" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "该生产订单归属的项目编号" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "无法完成生产订单,存在未关闭的子生产订单" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "无法完成生产订单,存在未完成的产出项" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "生产分配任务卸载失败" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "生产订单 {build} 已完成" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "生产订单已完成" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "可追溯零件必须填写序列号" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "未指定产出" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "产出已完成" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "产出与生产订单不匹配" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "数量必须大于零" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "数量不能大于产出数量" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "产出未通过所有必要测试" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "已分配的库存物料仍在生产中" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" msgstr "存在已分配物料时无法部分完成生产输出" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "生产订单行项目" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "生产对象" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "数量" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "生产订单所需数量" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "库存消耗量" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "生产项必须指定产出,因为主零件已经被标记为可追踪的" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "所选库存项与物料清单行项不匹配" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" msgstr "分配的数量必须大于零" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "序列化物料的数量必须为1" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "分配数量 ({q}) 不得超过可用库存数量 ({a})" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "库存品项超额分配" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "库存项" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "源库存项" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "分配给该生产任务的库存量" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "安裝到" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "目标库存项" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "生产等级" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "零件名称" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "产出" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "生产产出与上级订单不匹配" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "产出零件与生产订单零件不匹配" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "此产出已经完成" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "此产出尚未完全分配" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "输入产出数量" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "可追踪的零件数量必须为整数" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "因为物料清单包含可追踪的零件,所以数量必须为整数" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "序列号" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "输入产出的序列号" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "生产产出的库存地点" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "自动分配序列号" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "自动为所需项目分配对应的序列号" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "以下序列号已存在或无效" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "必须提供产出清单" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "报废品库存地点" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "放弃分配" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "取消对报废产品的库存分配" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "废品产出的原因" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "完工产出存放库位" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "接受不完整的分配" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "如果库存尚未全部分配,则完成产出" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "消耗已分配库存" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "立即扣除已分配给该生产任务的库存" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "移除未完成的产出" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "删除所有未完成的产出" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "禁止操作" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "标记为当前生产订单消耗" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "完成此生产订单前取消分配" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "超额分配库存" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "如何处理分配给生产订单的超额库存" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "存在超额分配的库存项" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "接受未分配" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "接受库存项未被完全分配至生产订单" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "必需库存未完成全量分配" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "接受未完工" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "允许所需数量的产出未完成" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "生产需求数量未完成" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "生产订单有打开的子生产订单" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "生产订单必须处于生产状态" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "生产订单有未完成的产出" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "生产行" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "产出" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "生产产出必须指向相同的生产" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "生产行项目" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part 必须与生产订单零件相同" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "项目必须在库存中" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "可用量 ({q}) 超出限制" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "对于被追踪的零件的分配,必须指定生产产出" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "对于未被追踪的零件,无法指定生产产出" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "必须提供分配项目" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "零件来源的库存地点(留空则可来源于任何库存地点)" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "排除位置" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "从该选定的库存地点排除库存项" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "可互换库存" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "在多个位置的库存项目可以互换使用" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "替代品库存" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "允许分配可替换的零件" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "可选项目" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "分配可选的物料清单给生产订单" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "所有物料" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "未跟踪的物品" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "已跟踪的物品" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "物品类型" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "选择要自动分配的条目类型" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "启动自动分配任务失败" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "物料清单参考" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "物料清单零件识别号码" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "物料清单零件名称" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "安裝到" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "生产" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "供应商零件" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "已分配数量" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "生产订单编号" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "零件类别名称" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "可追踪" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "已继承的" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "允许变体" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "物料清单项" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "生产中" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "生产计划" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "外部库存" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "可用库存" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "可用的替代品库存" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "可用的变体库存" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "消耗数量超过分配数量" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "库存消耗可选备注" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "生产物料项必须关联到正确的生产订单" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "重复的生产物料项分配" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "订单行项目必须关联到正确的生产订单" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "重复的订单行项目分配" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "必须提供至少一个物料项或行项目" @@ -1495,43 +1479,47 @@ msgstr "已暂停" msgid "Cancelled" msgstr "已取消" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "完成" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "生产订单所需库存" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "生产订单{build}需补充库存" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "逾期的生产订单" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "生产订单 {bo} 现已逾期" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "是否链接" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "是否为文件" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "用户没有权限删除此附件" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "用户没有编辑此附件的权限" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "用户没有权限删除此附件" @@ -1551,798 +1539,822 @@ msgstr "未提供有效的货币代码" msgid "No plugin" msgstr "暂无插件" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "项目编号标签" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "已是最新" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "最后更新时间戳" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "更新于" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "上次修改该对象的用户" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "唯一项目编码" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "项目描述" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "负责此项目的用户或团队" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "设置密钥" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "设定值" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "所选值不是一个有效的选项" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "该值必须是布尔值" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "该值必须为整数" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "必须是有效数字" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "值未通过验证检查" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "键字符串必须是唯一的" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "使用者" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "批发价数量" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "价格" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "指定数量的单位价格" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "端点" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "接收此网络钩子的端点" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "此网络钩子的名称" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "激活" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "网络钩子是否已启用" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "令牌" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "访问令牌" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "密钥" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "HMAC共享密钥" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "消息ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "此邮件的唯一标识符" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "主机" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "接收此消息的主机" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "标题" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "此消息的标题" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "正文" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "此消息的正文" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "接收此消息的终点" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "工作于" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "这条消息的工作完成了吗?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "标识" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "标题" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "链接" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "已发布" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "作者" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "摘要" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "阅读" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "这条新闻被阅读了吗?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "图像文件" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "此图像的目标模型类型" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "此图像的目标型号ID" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "自定义单位" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "单位符号必须唯一" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "单位名称必须是有效的标识符" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "单位名称" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "符号" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "可选单位符号" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "定义" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "单位定义" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "附件" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "缺少文件" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "缺少外部链接" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "没有要重命名的文件" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "文件名不能为空" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "无效的文件名" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "无法更改文件扩展名" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "已存在同名文件" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "重命名文件保存失败" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "模型类型" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "图片的目标模型类型" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "选择附件" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "备注" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "附件备注" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "上传日期" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "上传文件的日期" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "文件大小" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "文件大小,以字节为单位" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "为附件指定的模型类型无效" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "自定状态" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "定制状态" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "参考状态设置" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "使用此自定义状态扩展状态的状态集" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "逻辑密钥" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "等同于商业逻辑中自定义状态的状态逻辑键" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "值" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "将保存至模型数据库的数值" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "状态名" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "标签" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "将在前端显示的标签" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "颜色" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "将在前端显示颜色" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "型号" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "该状态关联的模型" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "必须选定模型" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "必须选取密钥" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "必须选中逻辑密钥" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "密钥必须不同于逻辑密钥" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "必须提供有效的参考状态类" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "密钥必须不同于参考状态的逻辑密钥" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "逻辑密钥必须在参考状态的逻辑键中" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "名称必须不同于参考状态的名称" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "选择列表" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "选择列表" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "选择列表的名称" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "选择列表的描述" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "已锁定" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "此选择列表是否已锁定?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "能否使用此选择列表?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "源插件" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "提供选择列表的插件" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "源字符串" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "可选字符串,用于标识本列表的数据来源" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "缺省项" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "本选择列表的默认选项" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "已创建" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "选择列表的创建日期和时间" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "最近更新" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "选择列表的最后更新时间" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "选择列表项" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "选择列表项" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "此选项归属的选择列表" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "选择列表项的值" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "选择列表项的标签" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "选择列表项的描述" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "该选择列表项是否处于激活状态?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "参数模板" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" msgstr "参数模板" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "勾选框参数不能有单位" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "复选框参数不能有选项" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "选择必须是唯一的" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "参数模板名称必须是唯一的" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" msgstr "此参数模板的目标模型类型" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "参数名称" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "单位" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "此参数的物理单位" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "参数说明" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "勾选框" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "此参数是否为勾选框?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "选项" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "此参数的有效选择 (逗号分隔)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "此参数的选择列表" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "已启用" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" msgstr "此参数模板是否启用?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" msgstr "参数" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" msgstr "参数" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "无效的参数值选择" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" msgstr "为附件指定的模型类型无效" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" msgstr "型号ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" msgstr "此参数的目标模型的 ID" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "模板" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" msgstr "参数模板" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "数据" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "参数值" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "备注" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "可选注释字段" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "扫描条码" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "条码数据" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "扫描条码的用户" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "时间戳" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "扫描条形码的日期和时间" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "处理条码的 URL 端点" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "上下文" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "扫描条形码的上下文数据" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "响应" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "扫描条形码的响应数据" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "结果" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "条码扫描成功吗?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "发生错误" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "电子邮件信息" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "电子邮箱信息" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "已发布" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "已发送" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "失败" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "已送达" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "已确认" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "入站" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "出站" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "暂无回复消息" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "跟踪交付" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "已读追踪" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "点击追踪" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "全局ID" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "此消息的标识符 (可能由外部系统提供)" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "主题 ID" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "此消息主题的标识符 (可能由外部系统提供)" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "主题" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "链接到此消息的主题" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" msgstr "优先" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "邮件主题" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "邮件主题" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "键" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "此主题的唯一密钥 (用于识别主题)" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "此主题的唯一标识符" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "内部服务已启动" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "该线程是否为内部启动的?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "创建主题的日期和时间" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "主题最后更新的日期和时间" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "收到的物品" @@ -2392,1235 +2404,1303 @@ msgstr "表示设置是否被环境变量覆盖" msgid "Override" msgstr "覆盖" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "正在运行" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "等待完成的任务" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "预定的任务" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "失败的任务" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "任务ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "唯一任务ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "锁定" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "锁定时间" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "任务名称" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "功能" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "功能名称" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "参数" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "任务参数" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "关键字参数" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "任务关键词参数" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "文件名" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "模型类型" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "用户无权为此模式创建或编辑附件" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" msgstr "用户没有权限为此模型创建或编辑参数" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "选择列表已锁定" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "无分组" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "网站 URL 已配置为锁定" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "需要重启" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "设置已更改,需要服务器重启" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "等待迁移" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "待处理的数据库迁移数" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "活动的警告代码" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "活跃警告代码的字典" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "实例ID" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "此 InvenTree 实例的唯一标识符" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "公告 ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "在服务器状态信息中公开实例ID(未认证状态下)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "服务器实例名称" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "服务器实例的字符串描述符" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "使用实例名称" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "在标题栏中使用实例名称" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "限制显示 `关于` 信息" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "只向超级管理员显示关于信息" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "显示超级用户横幅" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "以超级用户身份登录时,在用户界面中显示警告横幅" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "显示管理员横幅" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "以管理员身份登录时,在用户界面中显示警告横幅" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "公司名称" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "内部公司名称" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "基本 URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "服务器实例的基准 URL" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "默认货币" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "系统价格计算使用的基准货币" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "支持币种" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "支持的货币代码列表" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "货币更新间隔时间" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "检查更新的频率(设置为零以禁用)" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "天" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "币种更新插件" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "使用货币更新插件" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "从URL下载" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "允许从外部 URL 下载远程图片和文件" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "下载大小限制" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "远程图片的最大允许下载大小" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "用于从 URL 下载的 User-agent" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "允许覆盖用于从外部 URL 下载图片和文件的 user-agent(留空为默认值)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "严格的 URL 验证" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "验证 URL 时需要 schema 规范" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "更新检查间隔" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "检查更新的频率(设置为零以禁用)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "自动备份" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "启用数据库和媒体文件的自动备份" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "自动备份间隔" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "指定自动备份之间的间隔天数" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "任务删除间隔" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "后台任务结果将在指定天数后删除" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "错误日志删除间隔" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "错误日志将在指定天数后被删除" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "通知删除间隔" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "用户通知将在指定天数后被删除" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "邮件自动清理周期" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "邮件将在指定天数后删除" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "保护邮件日志" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "防止邮件日志条目被删除" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "条形码支持" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "在网页界面启用条形码扫描器支持" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "存储条形码结果" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "存储条形码扫描结果" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "条形码扫描最大计数" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "保存的条形码扫描结果的最大数量" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "条形码扫描延迟设置" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "条形码输入处理延迟时间" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "启用摄像头扫码支持" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "允许通过网络摄像头扫描条形码" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "显示条形码数据" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "在浏览器中将条形码数据显示为文本" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "条形码生成插件" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "用于内部条形码数据生成的插件" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "零件修订" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "启用零件修订字段" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "仅限装配修订版本" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "仅允许对装配零件进行修订" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "允许从装配中删除" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "允许删除已在装配中使用的零件" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN(内部零件号)正则规则" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "用于匹配IPN(内部零件号)格式的正则表达式" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "允许重复的 IPN(内部零件号)" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "允许多个零件共享相同的 IPN(内部零件号)" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "允许编辑 IPN(内部零件号)" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "允许编辑零件时更改IPN(内部零件号)" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "复制零件物料清单数据" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "复制零件时默认复制物料清单数据" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "复制零件参数数据" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "复制零件时默认复制参数数据" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "复制零件测试数据" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "复制零件时默认复制测试数据" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "复制类别参数模板" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "创建零件时复制类别参数模板" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "零件默认为模板" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "默认情况下,元件可由其他零件组装而成" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "组件" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "默认情况下,零件可用作子部件" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "可购买" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "默认情况下可购买零件" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "可销售" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "零件默认为可销售" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "默认情况下可跟踪零件" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "虚拟的" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "默认情况下,零件是虚拟的" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "显示关联零件" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "显示零件的关联零件" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "允许创建初始库存" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "允许在添加新零件时创建初始库存数据" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "允许创建供应商数据" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "允许在添加新零件时创建初始供应商数据" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "零件名称显示格式" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "显示零件名称的格式" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "零件类别默认图标" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "零件类别默认图标 (空表示没有图标)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "最小定价小数位数" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "呈现定价数据时显示的最小小数位数" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "最大定价小数位数" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "呈现定价数据时显示的最大小数位数" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "使用供应商定价" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "将供应商的批发价纳入整体价格计算" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "采购历史价优先" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "当存在历史采购订单价格时,将忽略供应商的批发价" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "使用库存项定价" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "使用手动输入的库存数据进行定价计算" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "库存项目定价时间" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "从定价计算中排除超过此天数的库存项目" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "使用变体定价" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "将产品变体的特殊定价纳入整体价格计算" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "仅限活跃变体" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "仅使用活跃变体零件计算变体价格" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "自动更新定价" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "当内部数据变化时自动更新零件价格" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "价格重建间隔" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "零件价格自动更新前的天数" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "内部价格" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "为零件启用内部核算价格功能" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "内部价格优先" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "若存在内部价格,将覆盖BOM价格区间计算结果" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "允许BOM数量为零" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "启用标签打印功能" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "启用从网络界面打印标签" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "标签图片 DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "生成图像文件以供标签打印插件使用时的 DPI 分辨率" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "启用报告" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "启用报告生成" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "调试模式" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "以调试模式生成报告(HTML 输出)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "日志错误报告" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "记录生成报告时出现的错误" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "页面大小" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "PDF 报告默认页面大小" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "强制参数单位" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "如果提供了单位,参数值必须与指定的单位匹配" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "全局唯一序列号" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "库存项的序列号必须全局唯一" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "删除已耗尽的库存" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "设置库存耗尽时的默认行为" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "删除序列化库存" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "允许删除带有序列号的库存商品" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "批号模板" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "为库存项生成默认批号的模板" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "库存过期" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "启用库存过期功能" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "销售过期库存" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "允许销售过期库存" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "库存临期预警天数" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "库存项过期前被标记为\"临期\"的天数" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "允许使用过期库存" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "允许在生产中使用已过期的库存" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "库存所有权管控" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "启用对库存地点和库存物品的归属权管理" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "库存地点默认图标" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "库存地点默认图标 (空表示没有图标)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "显示已安装的库存项" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "在库存列表中显示已被安装到设备中的库存项" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "在安装项目时检查物料清单" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "已安装的库存项目必须存在于上级零件的物料清单中" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "允许零库存调拨" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "生产订单参考模式" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "生成生产订单参考字段所需的模式" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "需要活动零件" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "防止为非活动零件创建生产订单" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "需要锁定零件" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "防止为未锁定的零件创建生产订单" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "需要有效的物料清单" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "除非物料清单已验证,否则禁止创建生产订单" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "需要关闭子订单" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "在所有子订单关闭之前,阻止生产订单的完成" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "外部生产订单" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "启用外部生产订单功能" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "需要外部生产订单" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "从外部供应商订购组装好的零件时,需要外部生产订单" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "阻止直到测试通过" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "在所有必要的测试通过之前,阻止产出完成" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "启用订单退货" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "在用户界面中启用订单退货功能" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "退货订单参考模式" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "生成退货订单参考字段所需的模式" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "编辑已完成的退货订单" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "允许编辑已完成的退货订单" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "销售订单参考模式" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "生成销售订单参考字段所需参照模式" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "销售订单默认配送方式" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "启用创建销售订单的默认配送功能" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "编辑已完成的销售订单" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "允许在订单配送或完成后编辑销售订单" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" msgstr "货件需核对" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" msgstr "只有所有物品均经核对,才能确认发货完成" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "标记该订单为已完成?" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "标记为已发货的销售订单将自动完成,绕过“已发货”状态" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "生成采购订单参考字段所需的模式" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "编辑已完成的采购订单" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "允许在采购订单已配送或完成后编辑订单" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "货币转换" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "收货时将物料价值折算为基准货币" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "自动完成采购订单" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "当收到所有行项目时,自动将采购订单标记为完成" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "忘记启用密码" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "在登录页面上启用忘记密码功能" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "启用注册" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "在登录页面为用户启用自行注册功能" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "启用SSO登录" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "在登录页面启用单点登录(SSO)功能" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "启用SSO注册" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "允许用户通过登录页面的SSO系统注册账号" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "启用SSO组同步" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "启用后,将自动同步InvenTree用户组与身份提供商(IdP)提供的用户组" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "SSO组属性键" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "身份提供商(IdP)返回的组信息声明属性名称" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "SSO组映射关系" -#: common/setting/system.py:966 +#: 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 "将SSO用户组映射到本地InvenTree用户组的对应关系表。如果本地组不存在,系统会自动创建对应的用户组。" -#: common/setting/system.py:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "移除非SSO来源的用户组" -#: common/setting/system.py:974 +#: 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:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "必须提供邮箱" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "用户注册时必须提供邮箱" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "自动填充SSO用户信息" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "自动从SSO账户数据中填充用户详细信息" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "发两次邮件" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "注册时询问用户他们的电子邮件两次" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "两次输入密码" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "当注册时请用户输入密码两次" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "域名白名单" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "限制注册到某些域名 (逗号分隔,以 @ 开头)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "注册默认分组" -#: common/setting/system.py:1014 +#: 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." msgstr "新用户注册时被分配的默认用户组。 如果启用了SSO组同步功能,当无法从身份提供商(IdP)分配组时才会应用此分组。" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "强制启用多因素安全认证" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "用户必须使用多因素安全认证。" -#: common/setting/system.py:1026 +#: 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:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "启动时检查插件" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "启动时检查全部插件是否已安装 - 在容器环境中启用" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "检查插件更新" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "启用定期检查已安装插件的更新" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "启用统一资源定位符集成" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "启用插件以添加统一资源定位符路由" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "启用导航集成" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "启用插件以集成到导航中" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "启用应用集成" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "启用插件添加应用" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "启用调度集成" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "启用插件来运行预定任务" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "启用事件集成" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "启用插件响应内部事件" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "启用界面集成" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "启用插件集成到用户界面" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "启用邮件集成" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "启用插件来处理发送/接收邮件" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "启用项目编码" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "启用项目编码来跟踪项目" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" -msgstr "" +msgstr "启用盘点" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "启用历史库存水平及价值记录功能" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "排除外部地点" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "将外部库位的库存物料排除在盘点计算之外" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "自动盘点周期" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "自动库存盘点记录的间隔天数" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "删除旧的盘点记录条目" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "删除超过指定天数的库存盘点记录" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "库存盘点记录删除周期" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "库存盘点记录将在指定天数后自动删除" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "删除旧的库存跟踪记录" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +msgstr "删除超过指定天数的库存跟踪记录" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "库存跟踪记录删除周期" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgstr "库存跟踪记录将在指定天数后自动删除" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "显示用户全名" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "显示用户全名而不是用户名" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "显示用户配置" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "在用户个人资料页展示其档案信息" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "星期五" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "星期六" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "启用测试站数据" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "启用测试站数据收集以获取测试结果" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" msgstr "启用设备状态检测" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" msgstr "启用定期 Ping 检测,确认注册设备的运行状态" @@ -3907,21 +3987,37 @@ msgstr "禁用时:完整分类路径以悬停提示框形式显示。\n" "启用时:完整分类路径以纯文本形式显示。" #: 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" +msgstr "启用物料清单表中的子装配显示" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "接收错误报告" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "接收系统错误通知" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "上次使用的打印设备" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "为用户保存上次使用的打印设备" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "最终级别的展示项目" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "对于没有子项的位置或类别,自动默认显示项目/零件,而不是子级别" + #: common/validators.py:38 msgid "All models" msgstr "全部型号" @@ -3967,365 +4063,369 @@ msgstr "零件已激活" msgid "Manufacturer is Active" msgstr "制造商处于活动状态" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "供应商零件处于激活状态" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" -msgstr "" +msgstr "主供应商部件" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "内部零件已激活" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "供应商已激活" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "制造商" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "公司" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "有库存" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "公司" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "公司简介" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "公司简介" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "网站" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "公司网站" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "电话号码" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "联系电话" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "联系人电子邮箱地址" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "联系人" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "联络点" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "外部公司信息链接" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "这家公司是否激活?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "是客户" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "你是否向该公司出售商品?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "是否为供应商" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "你从这家公司买东西吗?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "是制造商吗" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "这家公司生产零件吗?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "此公司使用的默认货币" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "税号" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "公司税号" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "地址" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "地址" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "选择公司" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "地址标题" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "描述地址条目的标题" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "主要地址" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "设置主要地址" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "第1行" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "地址行1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "第2行" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "地址行2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "邮政编码" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "城市/地区" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "邮政编码城市/地区" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "省/市/自治区" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "省、自治区或直辖市" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "国家/地区" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "地址所在国家" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "快递运单" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "运输快递注意事项" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "内部装运通知单" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "内部使用的装运通知单" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "链接地址信息 (外部)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "制造商零件" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "基础零件" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "选择零件" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "选择制造商" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "制造商零件编号" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "制造商零件编号" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "外部制造商零件链接的URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "制造商零件说明" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "包装单位必须与基础零件单位兼容" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "包装单位必须大于零" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "链接的制造商零件必须引用相同的基础零件" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "供应商" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "选择供应商" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "供应商库存管理单位" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "此供应商零件是否处于活动状态?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "主要的" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgstr "这是否为关联物料的主供应商物料?" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "选择制造商零件" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "外部供应商零件链接的URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "供应商零件说明" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "基本费用" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "最低费用(例如库存费)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "打包" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "零件打包" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "包装数量" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "单包供应的总数量。为单个项目留空。" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "多个" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "订购多个" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "供应商提供的数量" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "可用性已更新" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "上次更新可用性数据的日期" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "供应商批发价" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "此供应商使用的默认货币" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "公司名称" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "有库存" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" msgstr "批发价" +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "美化名称" + #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" msgstr "数据导出过程中发生错误" @@ -4430,67 +4530,67 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "记录的现有数据库标识符" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "列已映射到数据库字段" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "字段已映射到数据列" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "列映射必须链接到有效的导入会话" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "数据文件中不存在列" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "目标模型中不存在字段" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "所选字段为只读" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "导入会话" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "字段" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "列" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "行索引" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "原始行数据" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "错误" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "有效" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "更新现有记录需要提供ID。" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" msgstr "没有找到与提供的ID相关的记录" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" msgstr "提供的ID格式无效" @@ -4590,7 +4690,7 @@ msgstr "每个标签要打印的份数" msgid "Connected" msgstr "已连接" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "未知" @@ -4694,7 +4794,7 @@ msgstr "属性键" msgid "Value of the property" msgstr "属性值" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "组" @@ -4722,7 +4822,7 @@ msgstr "进度类型的最大值。当 type=progress 时为必填项" msgid "Order Reference" msgstr "订单参考" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "未完成" @@ -4730,7 +4830,7 @@ msgstr "未完成" msgid "Has Project Code" msgstr "有项目编码" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "创建人" @@ -4766,57 +4866,69 @@ msgstr "目标日期早于" msgid "Target Date After" msgstr "目标日期晚于" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "更新时间早于" + +#: order/api.py:236 +msgid "Updated After" +msgstr "更新时间晚于" + +#: order/api.py:287 msgid "Has Pricing" msgstr "有定价" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "完成时间早于" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "完成时间晚于" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "外部生产订单" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "订单" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "订单完成" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "内部零件" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "订单待定" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "已完成" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "有配送" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "未找到发货记录" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "采购订单" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4824,8 +4936,8 @@ msgstr "采购订单" msgid "Sales Order" msgstr "销售订单" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4841,11 +4953,11 @@ msgstr "总价格" msgid "Total price for this order" msgstr "此订单的总价" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "订单货币" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "此订单的货币 (留空以使用公司默认值)" @@ -4853,718 +4965,750 @@ msgstr "此订单的货币 (留空以使用公司默认值)" msgid "This order is locked and cannot be modified" msgstr "该订单已锁定,不可修改" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "联系人与所选公司不匹配" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "开始日期必须早于目标日期" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" msgstr "地址与所选公司不匹配" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "订单描述 (可选)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "为此订单选择项目编码" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "链接到外部页面" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "开始日期" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "本订单的预定开始日期" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "预计日期" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "订单交付的预期日期。订单将在此日期后过期。" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "签发日期" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "订单发出日期" #: order/models.py:506 +msgid "Updated At" +msgstr "更新时间" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "负责此订单的用户或组" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "此订单的联系人" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "此订单的公司地址" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "订单参考" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "狀態" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "采购订单状态" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "订购物品的公司" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "供应商参考" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "供应商订单参考代码" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "接收人" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "订单完成日期" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "目的地" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "接收物品的目标" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "零件供应商必须与采购订单供应商匹配" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "行项目与采购订单不匹配" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "行项目缺少关联零件" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "数量必须是正数" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "客户" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "出售物品的公司" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "销售订单状态" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "客户参考 " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "客户订单参考代码" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "发货日期" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "发货人" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "订单已完成" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "订单已取消" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "只有未结订单才能标记为已完成" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "由于发货不完整,订单无法完成" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "由于缺货,订单无法完成" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "订单无法完成,因为行项目不完整" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "订单已锁定,不可修改" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "项目数量" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "行号" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "此项目的行号(可选)" + +#: order/models.py:1839 msgid "Line item reference" msgstr "行项目参考" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "行项目注释" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "此行项目的目标日期 (留空以使用订单中的目标日期)" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "行项目描述 (可选)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "此行的附加上下文" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "单位价格" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "采购订单行项目" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "供应商零件必须与供应商匹配" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "生产订单必须标记为外部" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "生产订单仅可关联至装配零件" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "生产订单零件必须与行项目零件一致" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "已接收" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "收到的物品数量" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "采购价格" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "每单位的采购价格" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "外部生产订单需由此行项目履行" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "采购订单附加行" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "销售订单行项目" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "只有可销售的零件才能分配给销售订单" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "售出价格" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "单位售出价格" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "已配送" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "发货数量" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "销售订单发货" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" msgstr "收货地址必须与该客户的资料一致" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" msgstr "本次发货的收货地址" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "发货日期" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "送达日期" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "装运交货日期" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "审核人" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "检查此装运的用户" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "配送" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "配送单号" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "跟踪单号" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "配送跟踪信息" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "发票编号" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "相关发票的参考号" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "货物已发出" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "发货没有分配库存项目" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" msgstr "货件必须先经核对,方可标记为完成" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "销售订单加行" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "销售订单分配" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "库存项目尚未分配" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "无法将库存项目分配给具有不同零件的行" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "无法将库存分配给没有零件的生产线" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "分配数量不能超过库存数量" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "分配的数量必须大于零" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "序列化库存项目的数量必须为1" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "销售订单与发货不匹配" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "发货与销售订单不匹配" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "行" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "销售订单发货参考" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "项目" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "选择要分配的库存项目" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "输入库存分配数量" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "退货订单参考" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "退回物品的公司" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "退货订单状态" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "退货订单行项目" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "必须指定库存项" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "退回数量超过库存数量" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "退回数量必须大于零" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "序列化库存项的数量无效" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "选择要从客户处退回的商品" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "接收日期" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" msgstr "收到此退货的日期" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "结果" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "该行项目的结果" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "与此行项目的退货或维修相关的成本" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "退货订单附加行" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "订单ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "要复制的订单ID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "复制行" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "从原始订单复制行项目" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "复制额外行" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "从原始订单复制额外的行项目" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "行项目" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "已完成行项目" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "复制订单" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "指定复制此订单的选项" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "订单ID不正确" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "供应商名称" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "订单不能取消" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "允许关闭行项目不完整的订单" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "订单中的行项目不完整" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "订单未打开" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "自动定价" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "根据供应商零件数据自动计算采购价格" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "购买价格货币" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "合并项目" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "将具有相同零件、目的地和目标日期的项目合并到一个行项目中" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "库存量单位" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "内部零件编号" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "内部零件名称" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "必须指定供应商零件" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "必须指定采购订单" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "供应商必须匹配采购订单" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "采购订单必须与供应商匹配" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "行项目" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "为收到的物品选择目的地位置" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "输入入库项目的批号" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "有效期至" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "输入入库库存项的有效期" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "输入入库库存项目的序列号" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "覆盖传入库存项目的包装资料" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "传入库存项目的附加说明" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "条形码" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "扫描条形码" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "条形码已被使用" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "必须提供行项目" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "必须指定目标位置" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "提供的条形码值必须是唯一的" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "配送" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "完成配送" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" -msgstr "" +msgstr "已分配的行" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "售出价格货币" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "已分配的项目" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "未提供装运详细信息" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "行项目与此订单不关联" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "数量必须为正" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "该库存项未通过所有必要的测试" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "输入要分配的序列号" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "货物已发出" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "发货与此订单无关" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "未找到以下序列号的匹配项" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "以下序列号不可用" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "退货订单行项目" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "行项目与退货订单不匹配" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "行项目已收到" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "只能根据正在进行的订单接收物品" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "退货数量" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "行价格货币" @@ -5600,146 +5744,150 @@ msgstr "退款" msgid "Reject" msgstr "拒绝" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "逾期采购订单" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "采购订单 {po} 已逾期" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "逾期销售订单" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "销售订单 {so} 已逾期" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "逾期退货订单" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "退货订单 {ro} 现已逾期" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "已加星标" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "按星标类别筛选" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "深度" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "按类别深度筛选" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "顶级" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "按顶级类别筛选" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "级联" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "在筛选结果中包含子类别" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "父类" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "按父类别筛选" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "排除指定类别下的子类别" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "有结果" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "是变体" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "是修订版本" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "有修订版本" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "物料清单合规" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" msgstr "级联分类" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" msgstr "如果为真,则包含给定分类下的所有子分类中的项目" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" msgstr "按数字分类ID或字面值 \"null\" 进行筛选" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" -msgstr "" +msgstr "装配零件已启用" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" -msgstr "" +msgstr "装配零件可追踪" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "装配部份是可测试的" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "装配零件已锁定" + +#: part/api.py:1316 msgid "Component part is active" -msgstr "" +msgstr "元器件已激活" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" -msgstr "" +msgstr "该零部件可追溯" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "组件部份是可测试的" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" -msgstr "" +msgstr "该零部件是一个装配件" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" -msgstr "" +msgstr "该零部件为虚拟件" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" -msgstr "" +msgstr "有可用库存" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "使用" @@ -5748,11 +5896,11 @@ msgstr "使用" msgid "Part Category" msgstr "零件类别" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "零件类别" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "默认位置" @@ -5780,7 +5928,7 @@ msgstr "此类别零件的默认关键字" msgid "Icon" msgstr "图标" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "图标(可选)" @@ -5801,1025 +5949,1050 @@ msgstr "默认值" msgid "Default Parameter Value" msgstr "默认参数值" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "零件" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" msgstr "无法删除已锁定零件的参数" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" msgstr "无法修改已锁定零件的参数" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "无法删除这个零件,因为它已被锁定" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "无法删除这个零件,因为它仍然处于活动状态" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "无法删除这个零件,因为它被使用在了装配中" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "零件 \"{self}\" 不能用在 \"{parent}\" 的物料清单 (递归)" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "零件 \"{parent}\" 被使用在了 \"{self}\" 的物料清单 (递归)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "内部零件号必须匹配正则表达式 {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "零件不能是对自身的修订" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "无法对已经是修订版本的零件进行修订" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "标记为带版本管理的物料必须指定版本代码" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "必须指定修订代码" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "修订仅对装配零件允许" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "无法对模版零件进行修订" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "上级零件必须指向相同的模版" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "该序列号库存项己存在" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "在零件设置中不允许重复的内部零件号" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "重复的零件修订版本已经存在。" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "有这个名字,内部零件号,和修订版本的零件已经存在" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "零件不能分配到结构性零件类别!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "零件名称" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "是模板" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "这个零件是一个模版零件吗?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "这个零件是另一零件的变体吗?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "变体" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "零件描述(可选)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "关键词" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "提高搜索结果可见性的零件关键字" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "零件类别" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "内部零件号 IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "零件修订版本或版本号" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "版本" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "这零件是另一零件的修订版本吗?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "修订版本" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "该物品通常存放在哪里?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "默认到期" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "此零件库存项的过期时间 (天)" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "最低库存" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "允许的最小库存量" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "最大库存" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "最大允许库存水平" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "此零件的计量单位" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "这个零件可由其他零件加工而成吗?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "这个零件可用于创建其他零件吗?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "此零件是否有唯一物品的追踪功能" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "这一部件能否记录到测试结果?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "这个零件可从外部供应商购买吗?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "此零件可以销售给客户吗?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "这个零件是否已激活?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "无法编辑锁定的零件" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "这是一个虚拟零件,例如一个软件产品或许可证吗?" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "物料清单已验证" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "该零件的物料清单是否通过验证?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "物料清单校验和" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "保存的物料清单校验和" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "物料清单检查人" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "物料清单检查日期" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "新建用户" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "此零件的负责人" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "出售多个" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "用于缓存定价计算的货币" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "最低物料清单成本" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "元件的最低成本" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "物料清单的最高成本" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "元件的最高成本" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "最低购买成本" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "最高历史购买成本" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "最大购买成本" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "最高历史购买成本" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "最低内部价格" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "基于内部批发价的最低成本" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "最大内部价格" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "基于内部批发价的最高成本" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "供应商最低价格" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "外部供应商零件的最低价格" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "供应商最高价格" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "来自外部供应商的商零件的最高价格" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "最小变体成本" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "计算出的变体零件的最低成本" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "最大变体成本" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "计算出的变体零件的最大成本" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "最低成本" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "覆盖最低成本" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "最高成本" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "覆盖最大成本" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "计算总最低成本" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "计算总最大成本" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "最低售出价格" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "基于批发价的最低售出价格" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "最高售出价格" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "基于批发价的最大售出价格" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "最低销售成本" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "历史最低售出价格" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "最高销售成本" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "历史最高售出价格" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "用于盘点的零件" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "物品数量" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "盘点时的个别库存条目数" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "盘点时可用库存总额" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "日期" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "进行盘点的日期" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "最低库存成本" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "现有存库存最低成本估算" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "最高库存成本" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "目前库存最高成本估算" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "零件售出价格折扣" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "零件测试模板" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "模板名称无效 - 必须包含至少一个字母或者数字" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "测试模板只能为可拆分的部件创建" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "零件已存在具有相同主键的测试模板" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "测试名" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "输入测试的名称" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "测试主键" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "简化测试主键" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "测试说明" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "输入测试的描述" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "此测试是否已启用?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "必须的" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "需要此测试才能通过吗?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "需要值" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "添加测试结果时是否需要一个值?" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "需要附件" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "添加测试结果时是否需要文件附件?" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "此测试的有效选择 (逗号分隔)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "数量无效 - 未指定零件的单位" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "数量必须大于或等于零" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "物料清单项目不能被修改 - 装配已锁定" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "物料清单项目不能修改 - 变体装配已锁定" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "选择父零件" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "子零件" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "选择要用于物料清单的零件" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "数量" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "生产一个部件所消耗的子零件数量" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "此物料清单项目的数量" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "此物料清单项目是可选的" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "这个物料清单项目是耗材 (它没有在生产订单中被追踪)" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "设置数量" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "为补偿生产准备损耗所需的额外数量" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "损耗" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "生产预估损耗率(百分比,0-100)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "舍入倍数" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "将所需生产数量向上舍入至该值的最接近倍数" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "物料清单项目引用" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "物料清单项目注释" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "校验和" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "物料清单行校验和" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "已验证" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "此物料清单项目已验证" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "获取继承的" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "此物料清单项目是由物料清单继承的变体零件" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "变体零件的库存项可以用于此物料清单项目" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "可追踪零件的数量必须是整数" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "必须指定子零件" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "物料清单项目替代品" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "替代品零件不能与主零件相同" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "上级物料清单项目" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "替代品零件" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "零件 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "零件2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "选择相关的零件" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "此关系的注释" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "零件关系不能在零件和自身之间创建" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "复制关系已经存在" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "上级类别" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "上级零件类别" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "子类别" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "结果" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "根据该模板记录的结果数量" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "购买此库存项的货币" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "文件不是一个图片" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "原始零件" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "选择要复制的原始零件" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "复制图片" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "从原零件复制图片" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "复制物料清单" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "从原始零件复制材料清单" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "复制参数" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "从原始零件复制参数数据" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "复制备注" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "从原始零件复制备注" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "复制测试" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "从原始零件复制测试模板" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "初始化库存数量" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "指定此零件的初始库存数量。如果数量为零,则不添加任何库存。" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "初始化库存地点" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "初始化指定此零件的库存地点" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "选择供应商(或为空以跳过)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "选择制造商(或为空)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "制造商零件号" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "所选公司不是一个有效的供应商" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "所选公司不是一个有效的制造商" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "与此制造商零件编号 (MPN) 的相匹配的制造商零件已存在" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "匹配此库存单位 (SKU) 的供应商零件已存在" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "类别名称" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "正在生产" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "目前正在生产的零件数量" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "此零件计划待产数量" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "库存项" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "修订" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "库存总量" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "未分配的库存" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "变体库存" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "重复零件" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "从另一个零件复制初始数据" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "初始库存" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "创建具有初始库存数量的零件" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "供应商信息" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "添加此零件的初始供应商信息" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "复制类别参数" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "从选择的零件复制参数模版" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "现有的图片" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "现有零件图片的文件名" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "图片不存在" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "验证整个物料清单" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "可以创建" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "生产订单必填项" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "分配到生产订单" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "销售订单必填项" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "分配到销售订单" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" -msgstr "" +msgstr "内部零件号" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "零件描述" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "选择一个物料,以生成该物料(及其所有变型物料)的盘点信息" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "选择一个分类,以包含该分类(及其子分类)下的所有物料" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "选择一个库位,以包含该库位(含子库位)中有库存的所有物料" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "生成盘点条目" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "保存所选物料的盘点条目" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" -msgstr "" +msgstr "生成报告" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" -msgstr "" +msgstr "为所选物料生成盘点报告" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "最低价格" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "覆盖已计算的最低价格值" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "最低价格货币" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "最高价格" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "覆盖已计算的最高价格值" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "最高价格货币" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "更新" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "更新这个零件的价格" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "无法将所提供的货币转换为 {default_currency}" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "最低价格不能高于最高价格。" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "最高价格不能低于最低价格" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "此商品所需数量(可包含单位)" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "选择父装配" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "选择零部件" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "无效的数量格式" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "选择要复制物料清单的零件" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "移除现有数据" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "复制前删除现有的物料清单项目" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "包含继承的" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "包含从模板零件继承的物料清单项目" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "跳过无效行" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "启用此选项以跳过无效行" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "复制替代品零件" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "复制物料清单项目时复制替代品零件" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "低库存通知" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "可用的 {part.name}库存已经跌到设置的最低值" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "到期库存通知" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "您有1个库存项即将到期" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "您有{item_count}个库存项即将到期" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "永久有效" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "已过期 {abs(days_diff)} 天" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "今天到期" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry}天" @@ -7033,15 +7206,15 @@ msgstr "待分配数" msgid "Label printing failed" msgstr "标签打印失败" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "渲染标签到 PDF 时出错" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "渲染标签到 HTML 时出错" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "没有要打印的项目" @@ -7102,7 +7275,7 @@ msgstr "提供条形码本地支持" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7448,20 +7621,20 @@ msgstr "零件变更通知" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "零件 `{part.name}`已触发 `{part_action}`事件" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF 标签打印机" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "为打印 PDF 标签提供本机支持" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Debug模式" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "启用Debug模式 - 返回原始的 HTML 而不是 PDF" @@ -7502,7 +7675,7 @@ msgstr "边框" msgid "Print a border around each label" msgstr "打印每个标签的边框" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "横屏模式" @@ -7582,64 +7755,77 @@ msgstr "为扫描 TME 条形码提供支持" msgid "The Supplier which acts as 'TME'" msgstr "作为‘TME’的供应商" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "只有员工用户可以管理插件" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "只有超级用户帐户可以管理插件" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "插件安装已禁用" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "没有为安装提供软件包名称或URL" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "包名或 URL 中有无效字符" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "插件安装成功" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "插件安装到 {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "在插件仓库中找不到插件" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "插件不是一个打包的插件" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "找不到插件包名称" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "只有员工用户可以管理插件" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "插件卸载已禁用" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "插件无法卸载,因为它目前处于激活状态" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "该插件为系统必需组件,无法卸载" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "该插件为示例插件,无法卸载" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "该插件为系统内置组件,无法卸载" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "插件未安装" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "未找到插件安装记录" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "插件卸载成功" @@ -7691,21 +7877,21 @@ msgstr "软件包插件" msgid "Plugin" msgstr "插件" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "未找到作者" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "插件 '{p}' 与当前 InvenTree 版本{v} 不兼容" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "插件所需最低版本 {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "插件所需最高版本 {v}" @@ -7886,55 +8072,55 @@ msgstr "安装尚未确认" msgid "Either packagename or URL must be provided" msgstr "必须提供软件包名称或者URL" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "完全重载" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "执行插件库的完整重载" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "强制重载" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "强制重载插件库,即使已经加载" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "收集插件" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "收集插件并添加到注册表中" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "激活插件" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "激活此插件" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "强制插件不可停用" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "删除配置" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "从数据库中删除插件配置" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "该设置项适用的目标用户" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "项目" @@ -7950,7 +8136,7 @@ msgstr "插件不支持标签打印" msgid "Invalid label dimensions" msgstr "无效的标签尺寸" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "没有有效的项目提供到模板" @@ -7974,152 +8160,156 @@ msgstr "字母" msgid "Template file with this name already exists" msgstr "已存在具有此名称的模板" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "模版名称" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "模板说明" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "修订编号 (自动增量)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "打印时附加到模型" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "打印时将报告输出保存为附件与链接模型实例" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "文件名样式" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "生成文件名模式" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "模板已启用" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "模版的目标模型类型" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "筛选器" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "模版查询筛选器 (逗号分隔的键值对列表)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "模板包文件" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "PDF 报告的页面大小" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "横向渲染报告" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "合并" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "针对选定项目生成独立报" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "基于模板 {self.name} 生成的报告" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "模板语法错误" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "报告渲染错误" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "报告生成错误" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "报告合并输出错误" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "宽度 [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "标签宽度,以毫米为单位。" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "高度 [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "标签高度,以毫米为单位。" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "标签打印错误" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "代码片段" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "报告代码片段文件" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "代码片段文件描述" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "资产" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "报告资产文件" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "资产文件描述" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "用户必须通过身份验证才能保存报告模板" + +#: report/serializers.py:118 msgid "Select report template" msgstr "选择报表模板" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "要包含在报告中的项目主键列表" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "选择标签模板" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "打印插件" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "选择用于标签打印的插件" @@ -8192,7 +8382,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "序列号" @@ -8217,7 +8407,7 @@ msgstr "库存项测试报告" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "已安装的项目" @@ -8250,186 +8440,198 @@ msgstr "无结果 (必填)" msgid "No result" msgstr "没有结果" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "资产文件不存在" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "无效的媒体文件路径" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "无效的静态文件路径" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "未找到资源文件" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "找不到图片文件" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "未指定图片文件" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "parpart_image 标签需要一个零件实例" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "公司_图片标签需要一个公司实例" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "按位置深度筛选" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "按顶级位置筛选" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "在筛选结果中包含子地点" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "上级地点" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "按上级位置筛选" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "零件名称 (不区分大小写)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "零件名称包含 (不区分大小写)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "零件名称 (正则表达式)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "内部零件号 (不区分大小写)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "内部零件号 (不区分大小写)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "内部零件号 (正则表达式)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "最低库存" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "最大库存" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "状态代码" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "外部地点" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "被生产订单消耗" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "安装于其他库存项中" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "零件树" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "更新时间早于" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "更新时间晚于" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "盘点时间早于" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "盘点时间晚于" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "过期日期前" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "过期日期后" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "过期" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" msgstr "提供库存项的主键(PK)以排除该项及其所有子项" -#: stock/api.py:981 +#: stock/api.py:980 msgid "Cascade Locations" msgstr "级联位置" -#: stock/api.py:982 +#: stock/api.py:981 msgid "If true, include items in child locations of the given location" msgstr "若为真,则包含给定位置的所有子位置中的项目" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "按数字位置ID或字母“null”筛选" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "请先输入数量" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "必须提供有效的零件" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "给定的供应商零件不存在" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "供应商零件有定义的包装大小,但 use_pack_size 标志未设置" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "不能为不可跟踪的零件提供序列号" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" msgstr "包含已安装项" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" msgstr "如果为真,则包含给定库存项下已安装组件的测试结果" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" msgstr "按数字库存项ID进行筛选" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "ID 为 {id} 的库存项不存在" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" -msgstr "" +msgstr "包含零件变体" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" -msgstr "" +msgstr "日期晚于" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" -msgstr "" +msgstr "日期早于" #: stock/models.py:73 msgid "Stock Location type" @@ -8443,19 +8645,19 @@ msgstr "库存地点类型" msgid "Default icon for all locations that have no icon set (optional)" msgstr "为所有没有图标的位置设置默认图标(可选)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "库存地点" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "库存地点" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "选择所有者" @@ -8463,7 +8665,7 @@ msgstr "选择所有者" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "外部" @@ -8483,274 +8685,282 @@ msgstr "该位置的库存地点类型" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "您不能将此库存地点设置为结构性,因为某些库存项已经位于它!" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "序列化库存商品无法删除" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} 不存在" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "必须指定零件" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "库存项不能存放在结构性库存地点!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "无法为虚拟零件创建库存项" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "零件类型 ('{self.supplier_part.part}') 必须为 {self.part}" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "有序列号的项目的数量必须是1" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "如果数量大于1,则不能设置序列号" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "项目不能属于其自身" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "如果is_building=True,则项必须具有构建引用" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "构建引用未指向同一零件对象" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "父级库存项" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "基础零件" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "为此库存项目选择匹配的供应商零件" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "这个库存物品在哪里?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "包装此库存物品存储在" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "安装于" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "此项目是否安装在另一个项目中?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "此项目的序列号" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "此库存项的批号" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "库存数量" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "源代码构建" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "为此库存项目构建" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "消费者" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "构建消耗此库存项的生产订单" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "采购订单来源" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "此库存商品的采购订单" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "目的地销售订单" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "库存物品的到期日。在此日期之后,库存将被视为过期" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "耗尽时删除" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "当库存耗尽时删除此库存项" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "购买时一个单位的价格" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "转换为零件" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "数量超过可用库存" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "零件未设置为可跟踪" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "数量必须是整数" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "数量不得超过现有库存量 ({self.quantity})" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "必须以列表形式提供序列号" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "数量不匹配序列号" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" msgstr "无法将库存分配到结构位置" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "测试模板不存在" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "库存项已分配到销售订单" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "库存项已安装在另一个项目中" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "库存项包含其他项目" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "库存项已分配给客户" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "库存项目前正在生产" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "序列化的库存不能合并" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "复制库存项" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "库存项必须指相同零件" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "库存项必须是同一供应商的零件" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "库存状态码必须匹配" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "库存项不能移动,因为它没有库存" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "库存项跟踪" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "条目注释" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "库存项测试结果" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "必须为此测试提供值" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "测试附件必须上传" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "此测试的值无效" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "测试结果" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "测试输出值" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "测验结果附件" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "测试备注" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "测试站" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "进行测试的测试站的标识符" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "已开始" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "测试开始的时间戳" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "已完成" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "测试结束的时间戳" @@ -8794,246 +9004,246 @@ msgstr "选择要生成序列号的零件" msgid "Quantity of serial numbers to generate" msgstr "要生成的序列号的数量" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "此结果的测试模板" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" msgstr "未找到适用于此零件的匹配测试" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "必须提供模板 ID 或测试名称" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "测试完成时间不能早于测试开始时间" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "父项" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "父库存项" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "添加时使用包装尺寸:定义的数量是包装的数量" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "包装规格" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "输入新项目的序列号" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "供应商零件编号" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "已过期" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "子项目" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "跟踪项目" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "此库存商品的购买价格,单位或包装" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "输入要序列化的库存项目数量" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "未提供库存项" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "数量不得超过现有库存量 ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "目标库存位置" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "此零件不能分配序列号" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "序列号已存在" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "选择要安装的库存项目" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "安装数量" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "输入要安装的项目数量" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "添加交易记录 (可选)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "安装数量必须至少为1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "库存项不可用" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "所选零件不在物料清单中" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "安装数量不得超过可用数量" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "已卸载项目的目标位置" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "选择要将库存项目转换为的零件" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "所选零件不是有效的转换选项" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "无法转换已分配供应商零件的库存项" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "库存项状态代码" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "选择要更改状态的库存项目" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "未选择库存商品" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "子位置" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "上级库存地点" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "零件必须可销售" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "物料已分配到销售订单" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "项目被分配到生产订单中" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "客户分配库存项目" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "所选公司不是客户" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "库存分配说明" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "必须提供库存物品清单" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "库存合并说明" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "允许不匹配的供应商" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "允许合并具有不同供应商零件的库存项目" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "允许不匹配的状态" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "允许合并具有不同状态代码的库存项目" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "必须提供至少两件库存物品" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "无更改" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "库存项主键值" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "库存项无现货" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "库存项已有现货" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "数量不得为负" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "库存交易记录" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "合并至现有库存" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "若可行,将退回项目合并至现有库存项" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "下一个序列号" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "上一个序列号" @@ -9371,227 +9581,247 @@ msgstr "最近使用令牌的时间" msgid "Revoked" msgstr "撤销" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "权限设置" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "查看" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "查看项目的权限" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "添加" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "添加项目的权限" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "更改" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "编辑项目的权限" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "删除" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "删除项目的权限" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "机器人" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "内部" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "访客" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "语言" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "用户首选语言" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "主题" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Web界面设置为 JSON - 不要手动编辑!" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "小部件" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "设置面板小部件为 JSON - 不要手动编辑!" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "显示名称" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "用户自定义的显示名称" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "职位" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "主要职务或职位" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "用户状态信息" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "用户地址信息" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "用户正在积极使用系统" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "用户首选联系信息" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "用户类型" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "请选择用户类型?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "组织" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "用户主要组织/附属关系" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "主组" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "用户主组" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "管理员" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "物料清单" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "采购订单" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "销售订单" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "退货订单" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "用户名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "用户的名字(不包括姓氏)" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "姓" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "用户的姓氏" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "用户的电子邮件地址" -#: users/serializers.py:309 -msgid "Staff" -msgstr "职员" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "用户必须经过身份验证" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "此用户是否拥有员工权限" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "只有超级用户可以为另一个用户创建令牌" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "管理员" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "该用户是否拥有管理员权限" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "超级用户" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "此用户是否为超级用户" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "此用户帐户是否已激活" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "只有超级用户可以调整此字段" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "密码" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "用户密码" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "覆盖警告" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "覆盖有关密码规则的警告" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "管理员" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "该用户是否拥有管理员权限" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "你没有权限创建用户" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "您的账户已创建。" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "请使用密码重置功能登录" -#: users/serializers.py:452 +#: users/serializers.py:497 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 519c825616..5734842f04 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-02-22 11:06+0000\n" -"PO-Revision-Date: 2026-02-22 11:09\n" +"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"PO-Revision-Date: 2026-05-19 07:09\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -21,43 +21,35 @@ msgstr "" msgid "API endpoint not found" msgstr "未找到 API 端點" -#: InvenTree/api.py:442 -msgid "List of items or filters must be provided for bulk operation" -msgstr "批次操作必須提供項目列表或篩選條件" +#: InvenTree/api.py:438 +msgid "List of items must be provided for bulk operation" +msgstr "必須提供項目清單以進行大量操作" -#: InvenTree/api.py:449 +#: InvenTree/api.py:445 msgid "Items must be provided as a list" msgstr "項目必須以列表形式提供" -#: InvenTree/api.py:457 +#: InvenTree/api.py:453 msgid "Invalid items list provided" msgstr "提供了無效的單位" -#: InvenTree/api.py:463 -msgid "Filters must be provided as a dict" -msgstr "篩選條件必須以字典 (dict) 格式提供" - -#: InvenTree/api.py:470 -msgid "Invalid filters provided" -msgstr "提供了無效的過濾器" - -#: InvenTree/api.py:475 +#: InvenTree/api.py:458 msgid "All filter must only be used with true" msgstr "all 篩選器只能在值為 true 時使用" -#: InvenTree/api.py:480 +#: InvenTree/api.py:463 msgid "No items match the provided criteria" msgstr "沒有項目符合所提供的條件" -#: InvenTree/api.py:504 +#: InvenTree/api.py:487 msgid "No data provided" msgstr "未提供資料" -#: InvenTree/api.py:520 +#: InvenTree/api.py:503 msgid "This field must be unique." -msgstr "" +msgstr "此欄位須唯一值。" -#: InvenTree/api.py:815 +#: InvenTree/api.py:832 msgid "User does not have permission to view this model" msgstr "用户沒有權限查閲當前模型。" @@ -96,7 +88,8 @@ msgid "Could not convert {original} to {unit}" msgstr "不能將 {original} 轉換到 {unit}" #: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:596 order/models.py:723 order/models.py:1018 +#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 +#: part/models.py:3946 msgid "Invalid quantity provided" msgstr "提供的數量無效" @@ -112,13 +105,13 @@ msgstr "輸入日期" msgid "Invalid decimal value" msgstr "無效的十進位數值" -#: InvenTree/fields.py:218 InvenTree/models.py:1233 build/serializers.py:499 -#: build/serializers.py:570 build/serializers.py:1788 company/models.py:822 -#: order/models.py:1783 +#: 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 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2952 stock/models.py:3076 stock/serializers.py:721 -#: stock/serializers.py:897 stock/serializers.py:1039 stock/serializers.py:1367 -#: stock/serializers.py:1456 stock/serializers.py:1655 +#: 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 msgid "Notes" msgstr "備註" @@ -131,75 +124,91 @@ msgstr "值' {name}' 未出現在模式格式中" msgid "Provided value does not match required pattern: " msgstr "提供的值與所需模式不匹配:" -#: InvenTree/helpers.py:600 +#: InvenTree/helpers.py:614 msgid "Cannot serialize more than 1000 items at once" msgstr "一次不能序列化超過 1000 個項目" -#: InvenTree/helpers.py:606 +#: InvenTree/helpers.py:620 msgid "Empty serial number string" msgstr "序號為空白" -#: InvenTree/helpers.py:635 +#: InvenTree/helpers.py:649 msgid "Duplicate serial" msgstr "複製序列號" -#: InvenTree/helpers.py:667 InvenTree/helpers.py:710 InvenTree/helpers.py:728 -#: InvenTree/helpers.py:735 InvenTree/helpers.py:754 +#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 +#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 #, python-brace-format msgid "Invalid group: {group}" msgstr "無效的群組:{group}" -#: InvenTree/helpers.py:698 +#: InvenTree/helpers.py:712 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "組範圍 {group} 超出了允許的數量 ({expected_quantity})" -#: InvenTree/helpers.py:764 +#: InvenTree/helpers.py:778 msgid "No serial numbers found" msgstr "未找到序列號" -#: InvenTree/helpers.py:771 +#: InvenTree/helpers.py:785 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "唯一序列號數量 ({n}) 必須與數量 ({q}) 相符" -#: InvenTree/helpers.py:901 +#: InvenTree/helpers.py:915 msgid "Remove HTML tags from this value" msgstr "從這個值中刪除 HTML 標籤" -#: InvenTree/helpers.py:980 +#: InvenTree/helpers.py:992 msgid "Data contains prohibited markdown content" msgstr "資料包含被禁止的 Markdown 內容" -#: InvenTree/helpers_model.py:139 +#: InvenTree/helpers_model.py:109 +msgid "Invalid URL: no hostname" +msgstr "無效的 URL:沒有主機名稱" + +#: InvenTree/helpers_model.py:114 +msgid "Invalid URL: hostname could not be resolved" +msgstr "無效的 URL:無法解析主機名稱" + +#: InvenTree/helpers_model.py:120 +msgid "URL points to a private or reserved IP address" +msgstr "URL 指向私有或保留的 IP 地址" + +#: InvenTree/helpers_model.py:197 +msgid "Too many redirects" +msgstr "重新導向次數過多" + +#: InvenTree/helpers_model.py:202 msgid "Connection error" msgstr "連接錯誤" -#: InvenTree/helpers_model.py:144 InvenTree/helpers_model.py:151 +#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 msgid "Server responded with invalid status code" msgstr "服務器響應狀態碼無效" -#: InvenTree/helpers_model.py:147 +#: InvenTree/helpers_model.py:212 msgid "Exception occurred" msgstr "發生異常" -#: InvenTree/helpers_model.py:157 +#: InvenTree/helpers_model.py:222 msgid "Server responded with invalid Content-Length value" msgstr "服務器響應的內容長度值無效" -#: InvenTree/helpers_model.py:160 +#: InvenTree/helpers_model.py:225 msgid "Image size is too large" msgstr "圖片尺寸過大" -#: InvenTree/helpers_model.py:172 +#: InvenTree/helpers_model.py:237 msgid "Image download exceeded maximum size" msgstr "圖片下載超出最大尺寸" -#: InvenTree/helpers_model.py:177 +#: InvenTree/helpers_model.py:242 msgid "Remote server returned empty response" msgstr "遠程服務器返回了空響應" -#: InvenTree/helpers_model.py:185 +#: InvenTree/helpers_model.py:250 msgid "Supplied URL is not a valid image file" msgstr "提供的 URL 不是一個有效的圖片文件" @@ -207,11 +216,11 @@ msgstr "提供的 URL 不是一個有效的圖片文件" msgid "Log in to the app" msgstr "登入此應用程式" -#: InvenTree/magic_login.py:41 company/models.py:174 users/serializers.py:201 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 msgid "Email" msgstr "電子郵件" -#: InvenTree/middleware.py:178 +#: InvenTree/middleware.py:192 msgid "You must enable two-factor authentication before doing anything else." msgstr "在進行任何其他操作前,必須先啟用雙因素驗證。" @@ -255,135 +264,110 @@ msgstr "參考欄位並須符合格式" msgid "Reference number is too large" msgstr "參考編號過大" -#: InvenTree/models.py:901 +#: InvenTree/models.py:903 msgid "Invalid choice" msgstr "無效的選項" -#: InvenTree/models.py:1022 common/models.py:1431 common/models.py:1858 -#: common/models.py:2119 common/models.py:2244 common/models.py:2513 -#: common/serializers.py:566 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1107 plugin/models.py:54 -#: report/models.py:216 stock/models.py:86 +#: 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 msgid "Name" msgstr "名稱" -#: InvenTree/models.py:1028 build/models.py:262 common/models.py:177 -#: common/models.py:2251 common/models.py:2364 common/models.py:2528 -#: company/models.py:553 company/models.py:813 order/models.py:445 -#: order/models.py:1828 part/models.py:1130 report/models.py:222 -#: report/models.py:815 report/models.py:841 +#: 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 #: report/templates/report/inventree_build_order_report.html:117 #: stock/models.py:92 msgid "Description" msgstr "描述" -#: InvenTree/models.py:1029 stock/models.py:93 +#: InvenTree/models.py:1031 stock/models.py:93 msgid "Description (optional)" msgstr "描述(選填)" -#: InvenTree/models.py:1044 common/models.py:2834 +#: InvenTree/models.py:1046 common/models.py:2944 msgid "Path" msgstr "路徑" -#: InvenTree/models.py:1149 +#: InvenTree/models.py:1151 msgid "Duplicate names cannot exist under the same parent" msgstr "同一個上層元件下不能有重複的名字" -#: InvenTree/models.py:1233 +#: InvenTree/models.py:1235 msgid "Markdown notes (optional)" msgstr "Markdown 註記(選填)" -#: InvenTree/models.py:1264 +#: InvenTree/models.py:1266 msgid "Barcode Data" msgstr "條碼資料" -#: InvenTree/models.py:1265 +#: InvenTree/models.py:1267 msgid "Third party barcode data" msgstr "第三方條碼資料" -#: InvenTree/models.py:1271 +#: InvenTree/models.py:1273 msgid "Barcode Hash" msgstr "條碼雜湊值" -#: InvenTree/models.py:1272 +#: InvenTree/models.py:1274 msgid "Unique hash of barcode data" msgstr "條碼資料的唯一雜湊值" -#: InvenTree/models.py:1353 +#: InvenTree/models.py:1355 msgid "Existing barcode found" msgstr "發現現有條碼" -#: InvenTree/models.py:1435 -msgid "Task Failure" -msgstr "任務失敗" - -#: InvenTree/models.py:1436 -#, python-brace-format -msgid "Background worker task '{f}' failed after {n} attempts" -msgstr "背景工作任務「{f}」在嘗試 {n} 次後失敗" - -#: InvenTree/models.py:1463 +#: InvenTree/models.py:1455 msgid "Server Error" msgstr "伺服器錯誤" -#: InvenTree/models.py:1464 +#: InvenTree/models.py:1456 msgid "An error has been logged by the server." msgstr "伺服器紀錄了一個錯誤。" -#: InvenTree/models.py:1506 common/models.py:1769 +#: InvenTree/models.py:1498 common/models.py:1781 #: 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:327 part/models.py:4173 +#: InvenTree/serializers.py:363 msgid "Must be a valid number" msgstr "必須是有效的數字" -#: InvenTree/serializers.py:369 company/models.py:216 part/models.py:3312 +#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 msgid "Currency" msgstr "貨幣" -#: InvenTree/serializers.py:372 part/serializers.py:1337 +#: InvenTree/serializers.py:408 part/serializers.py:1376 msgid "Select currency from available options" msgstr "從可用選項中選擇貨幣" -#: InvenTree/serializers.py:726 +#: InvenTree/serializers.py:758 msgid "This field may not be null." -msgstr "" +msgstr "此欄位不可為空白。" -#: InvenTree/serializers.py:732 +#: InvenTree/serializers.py:764 msgid "Invalid value" msgstr "無效值" -#: InvenTree/serializers.py:769 -msgid "Remote Image" -msgstr "遠程圖片" - -#: InvenTree/serializers.py:770 -msgid "URL of remote image file" -msgstr "遠程圖片文件的 URL" - -#: InvenTree/serializers.py:788 -msgid "Downloading images from remote URL is not enabled" -msgstr "未啓用從遠程 URL下載圖片" - -#: InvenTree/serializers.py:795 -msgid "Failed to download image from remote URL" -msgstr "從遠程URL下載圖像失敗" - -#: InvenTree/serializers.py:878 +#: InvenTree/serializers.py:865 msgid "Invalid content type format" -msgstr "" +msgstr "不合規的內容類型格式" -#: InvenTree/serializers.py:881 +#: InvenTree/serializers.py:868 msgid "Content type not found" -msgstr "" +msgstr "內容類型未發現" -#: InvenTree/serializers.py:887 +#: InvenTree/serializers.py:874 msgid "Content type does not match required mixin class" -msgstr "" +msgstr "內容類型與所需的 mixin 類別不符" #: InvenTree/setting/locales.py:20 msgid "Arabic" @@ -537,11 +521,11 @@ msgstr "中文 (簡體)" msgid "Chinese (Traditional)" msgstr "中文 (繁體)" -#: InvenTree/tasks.py:576 +#: InvenTree/tasks.py:677 msgid "Update Available" msgstr "有可用更新" -#: InvenTree/tasks.py:577 +#: InvenTree/tasks.py:678 msgid "An update for InvenTree is available" msgstr "有新的 InvenTree 更新可用" @@ -553,30 +537,30 @@ msgstr "無效的物理單位" msgid "Not a valid currency code" msgstr "無效的貨幣代碼" -#: build/api.py:54 order/api.py:116 order/api.py:275 order/api.py:1372 -#: order/serializers.py:122 +#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 +#: order/serializers.py:124 msgid "Order Status" msgstr "訂單狀態" -#: build/api.py:80 build/models.py:274 +#: build/api.py:81 build/models.py:277 msgid "Parent Build" msgstr "上層生產工單" -#: build/api.py:84 build/api.py:832 order/api.py:551 order/api.py:774 -#: order/api.py:1173 order/api.py:1448 stock/api.py:573 +#: 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 msgid "Include Variants" msgstr "包含變體" -#: build/api.py:100 build/api.py:460 build/api.py:846 build/models.py:280 -#: build/serializers.py:1228 build/serializers.py:1399 -#: build/serializers.py:1485 company/models.py:1032 company/serializers.py:435 -#: order/api.py:303 order/api.py:307 order/api.py:930 order/api.py:1186 -#: order/api.py:1189 order/models.py:1944 order/models.py:2110 -#: order/models.py:2111 part/api.py:1160 part/api.py:1163 part/api.py:1376 -#: part/models.py:527 part/models.py:3323 part/models.py:3466 -#: part/models.py:3524 part/models.py:3545 part/models.py:3567 -#: part/models.py:3708 part/models.py:3970 part/models.py:4389 -#: part/serializers.py:1286 part/serializers.py:1896 +#: 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 #: 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 @@ -585,9 +569,9 @@ 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:586 stock/api.py:1521 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:410 stock/serializers.py:591 -#: stock/serializers.py:930 templates/email/build_order_completed.html:17 +#: 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 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -596,193 +580,197 @@ msgstr "包含變體" msgid "Part" msgstr "零件" -#: build/api.py:120 build/api.py:123 build/serializers.py:1498 part/api.py:975 -#: part/api.py:1387 part/models.py:412 part/models.py:1148 part/models.py:3595 -#: part/serializers.py:1296 part/serializers.py:1712 stock/api.py:869 +#: 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 msgid "Category" msgstr "類別" -#: build/api.py:131 build/api.py:135 +#: build/api.py:132 build/api.py:136 msgid "Ancestor Build" msgstr "可測試部分" -#: build/api.py:152 order/api.py:134 +#: build/api.py:153 order/api.py:134 msgid "Assigned to me" msgstr "分配給我" -#: build/api.py:167 +#: build/api.py:168 msgid "Assigned To" msgstr "負責人" -#: build/api.py:202 +#: build/api.py:203 msgid "Created before" msgstr "建立於之前" -#: build/api.py:206 +#: build/api.py:207 msgid "Created after" msgstr "建立於之後" -#: build/api.py:210 +#: build/api.py:211 msgid "Has start date" msgstr "有開始日期" -#: build/api.py:218 +#: build/api.py:219 msgid "Start date before" msgstr "開始日期早於" -#: build/api.py:222 +#: build/api.py:223 msgid "Start date after" msgstr "開始日期晚於" -#: build/api.py:226 +#: build/api.py:227 msgid "Has target date" msgstr "有目標日期" -#: build/api.py:234 +#: build/api.py:235 msgid "Target date before" msgstr "目標日期早於" -#: build/api.py:238 +#: build/api.py:239 msgid "Target date after" msgstr "目標日期晚於" -#: build/api.py:242 +#: build/api.py:243 msgid "Completed before" msgstr "完成於之前" -#: build/api.py:246 +#: build/api.py:247 msgid "Completed after" msgstr "完成於之後" -#: build/api.py:249 order/api.py:231 +#: build/api.py:250 order/api.py:239 msgid "Min Date" msgstr "最小日期" -#: build/api.py:272 order/api.py:250 +#: build/api.py:273 order/api.py:258 msgid "Max Date" msgstr "最大日期" -#: build/api.py:297 build/api.py:300 part/api.py:212 stock/api.py:961 +#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 msgid "Exclude Tree" msgstr "排除樹" -#: build/api.py:399 +#: build/api.py:414 msgid "Build must be cancelled before it can be deleted" msgstr "工單必須被取消才能被刪除" -#: build/api.py:443 build/serializers.py:1429 part/models.py:4004 +#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 msgid "Consumable" msgstr "耗材" -#: build/api.py:446 build/serializers.py:1432 part/models.py:3998 +#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 msgid "Optional" msgstr "非必須項目" -#: build/api.py:449 build/serializers.py:1472 common/setting/system.py:470 -#: part/models.py:1253 part/serializers.py:1666 part/serializers.py:1685 -#: stock/api.py:639 +#: 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 msgid "Assembly" msgstr "裝配" -#: build/api.py:452 +#: build/api.py:467 msgid "Tracked" msgstr "追蹤中" -#: build/api.py:455 build/serializers.py:1435 part/models.py:1271 +#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 msgid "Testable" msgstr "可測試" -#: build/api.py:465 order/api.py:994 order/api.py:1362 +#: build/api.py:480 order/api.py:1006 order/api.py:1376 msgid "Order Outstanding" msgstr "訂單未完成" -#: build/api.py:475 build/serializers.py:1525 order/api.py:953 +#: build/api.py:490 build/serializers.py:1526 order/api.py:965 msgid "Allocated" msgstr "已分配" -#: build/api.py:484 build/models.py:1782 build/serializers.py:1448 +#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 msgid "Consumed" msgstr "已消耗" -#: build/api.py:493 company/models.py:877 company/serializers.py:414 +#: build/api.py:508 company/models.py:882 company/serializers.py:397 #: 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:517 build/serializers.py:1527 company/serializers.py:411 -#: order/serializers.py:1270 part/serializers.py:831 part/serializers.py:1152 -#: part/serializers.py:1721 +#: 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 msgid "On Order" msgstr "已訂購" -#: build/api.py:869 build/models.py:120 order/models.py:1977 +#: build/api.py:685 +msgid "Build not found" +msgstr "找不到生產記錄" + +#: build/api.py:955 build/models.py:120 order/models.py:2055 #: report/templates/report/inventree_build_order_report.html:105 #: stock/serializers.py:93 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "生產工單" -#: build/api.py:883 build/api.py:887 build/serializers.py:362 -#: build/serializers.py:487 build/serializers.py:557 build/serializers.py:1276 -#: build/serializers.py:1281 order/api.py:1233 order/api.py:1238 -#: order/serializers.py:791 order/serializers.py:931 order/serializers.py:2039 -#: part/serializers.py:1306 stock/api.py:987 stock/serializers.py:111 -#: stock/serializers.py:598 stock/serializers.py:714 stock/serializers.py:892 -#: stock/serializers.py:1449 stock/serializers.py:1770 -#: stock/serializers.py:1819 templates/email/stale_stock_notification.html:18 -#: users/models.py:549 +#: 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 msgid "Location" msgstr "地點" -#: build/api.py:895 part/serializers.py:1331 +#: build/api.py:981 part/serializers.py:1370 msgid "Output" -msgstr "" +msgstr "產出" -#: build/api.py:897 +#: build/api.py:983 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." -msgstr "" +msgstr "依產出庫存項目 ID 篩選。使用 'null' 尋找未安裝的生產項目。" -#: build/models.py:121 users/ruleset.py:31 +#: build/models.py:121 users/ruleset.py:33 msgid "Build Orders" msgstr "生產工單" -#: build/models.py:178 +#: build/models.py:181 msgid "Assembly BOM has not been validated" msgstr "裝配物料清單尚未驗證" -#: build/models.py:185 +#: build/models.py:188 msgid "Build order cannot be created for an inactive part" msgstr "無法為未激活的零件創建生產訂單" -#: build/models.py:192 +#: build/models.py:195 msgid "Build order cannot be created for an unlocked part" msgstr "無法為已解鎖的零件創建生產訂單" -#: build/models.py:210 +#: build/models.py:213 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "只有可採購的零件,生產工單才可進行外部履行" -#: build/models.py:217 order/models.py:371 +#: build/models.py:220 order/models.py:373 msgid "Responsible user or group must be specified" msgstr "必須指定負責的用户或組" -#: build/models.py:222 +#: build/models.py:225 msgid "Build order part cannot be changed" msgstr "無法更改生產工單" -#: build/models.py:227 order/models.py:384 +#: build/models.py:230 order/models.py:386 msgid "Target date must be after start date" msgstr "目標日期必須晚於開始日期" -#: build/models.py:255 +#: build/models.py:258 msgid "Build Order Reference" msgstr "生產工單代號" -#: build/models.py:256 build/serializers.py:1426 order/models.py:617 -#: order/models.py:1314 order/models.py:1776 order/models.py:2714 -#: part/models.py:4044 +#: 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 #: 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 @@ -790,234 +778,234 @@ msgstr "生產工單代號" msgid "Reference" msgstr "參考代號" -#: build/models.py:265 +#: build/models.py:268 msgid "Brief description of the build (optional)" msgstr "關於生產工單的簡單説明(選填)" -#: build/models.py:275 +#: build/models.py:278 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "分配此生產的生產訂單" -#: build/models.py:284 +#: build/models.py:287 msgid "Select part to build" msgstr "選擇要生產的零件" -#: build/models.py:289 +#: build/models.py:292 msgid "Sales Order Reference" msgstr "銷售訂單代號" -#: build/models.py:294 +#: build/models.py:297 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "分配此生產的銷售訂單" -#: build/models.py:299 build/serializers.py:1087 +#: build/models.py:302 build/serializers.py:1093 msgid "Source Location" msgstr "來源倉儲地點" -#: build/models.py:305 +#: build/models.py:308 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "選擇領取料件的倉儲地點(留白表示可以從任何地點領取)" -#: build/models.py:311 +#: build/models.py:314 msgid "External Build" msgstr "外部生產" -#: build/models.py:312 +#: build/models.py:315 msgid "This build order is fulfilled externally" msgstr "此生產工單由外部履行" -#: build/models.py:317 +#: build/models.py:320 msgid "Destination Location" msgstr "目標倉儲地點" -#: build/models.py:322 +#: build/models.py:325 msgid "Select location where the completed items will be stored" msgstr "選擇已完成項目庫存地點" -#: build/models.py:326 +#: build/models.py:329 msgid "Build Quantity" msgstr "生產數量" -#: build/models.py:329 +#: build/models.py:332 msgid "Number of stock items to build" msgstr "要生產的項目數量" -#: build/models.py:333 +#: build/models.py:336 msgid "Completed items" msgstr "已完成項目" -#: build/models.py:335 +#: build/models.py:338 msgid "Number of stock items which have been completed" msgstr "已經完成的庫存品數量" -#: build/models.py:339 +#: build/models.py:342 msgid "Build Status" msgstr "生產狀態" -#: build/models.py:344 +#: build/models.py:347 msgid "Build status code" msgstr "生產狀態代碼" -#: build/models.py:353 build/serializers.py:349 order/serializers.py:807 -#: stock/models.py:1105 stock/serializers.py:85 stock/serializers.py:1622 +#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 +#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 msgid "Batch Code" msgstr "批號" -#: build/models.py:357 build/serializers.py:350 +#: build/models.py:360 build/serializers.py:356 msgid "Batch code for this build output" msgstr "此產出的批號" -#: build/models.py:361 order/models.py:482 order/serializers.py:165 -#: part/models.py:1334 +#: build/models.py:364 order/models.py:484 order/serializers.py:179 +#: part/models.py:1338 msgid "Creation Date" msgstr "建立日期" -#: build/models.py:367 +#: build/models.py:370 msgid "Build start date" msgstr "生產開始日期" -#: build/models.py:368 +#: build/models.py:371 msgid "Scheduled start date for this build order" msgstr "預計此生產工單的開始日期" -#: build/models.py:374 +#: build/models.py:377 msgid "Target completion date" msgstr "目標完成日期" -#: build/models.py:376 +#: build/models.py:379 msgid "Target date for build completion. Build will be overdue after this date." msgstr "生產的預計完成日期。若超過此日期則工單會逾期。" -#: build/models.py:381 order/models.py:670 order/models.py:2753 +#: build/models.py:384 order/models.py:694 order/models.py:2834 msgid "Completion Date" msgstr "完成日期" -#: build/models.py:389 +#: build/models.py:392 msgid "completed by" msgstr "完成者" -#: build/models.py:398 +#: build/models.py:401 msgid "Issued by" msgstr "發布者" -#: build/models.py:399 +#: build/models.py:402 msgid "User who issued this build order" msgstr "發布此生產工單的使用者" -#: build/models.py:408 common/models.py:186 order/api.py:184 -#: order/models.py:507 part/models.py:1351 +#: build/models.py:419 common/models.py:189 order/api.py:184 +#: order/models.py:516 part/models.py:1355 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "負責人" -#: build/models.py:409 +#: build/models.py:420 msgid "User or group responsible for this build order" msgstr "負責此生產工單的使用者或羣組" -#: build/models.py:414 stock/models.py:1098 +#: build/models.py:425 stock/models.py:1124 msgid "External Link" msgstr "外部連結" -#: build/models.py:416 common/models.py:2007 part/models.py:1182 -#: stock/models.py:1100 +#: build/models.py:427 common/models.py:2089 part/models.py:1177 +#: stock/models.py:1126 msgid "Link to external URL" msgstr "外部URL連結" -#: build/models.py:421 +#: build/models.py:432 msgid "Build Priority" msgstr "製造優先度" -#: build/models.py:424 +#: build/models.py:435 msgid "Priority of this build order" msgstr "此生產工單的優先程度" -#: build/models.py:432 common/models.py:156 common/models.py:170 -#: order/api.py:170 order/models.py:454 order/models.py:1808 +#: build/models.py:443 common/models.py:159 common/models.py:173 +#: order/api.py:170 order/models.py:456 order/models.py:1870 msgid "Project Code" msgstr "專案代碼" -#: build/models.py:433 +#: build/models.py:444 msgid "Project code for this build order" msgstr "此生產工單隸屬的專案代碼" -#: build/models.py:686 +#: build/models.py:697 msgid "Cannot complete build order with open child builds" msgstr "無法完成仍有未結束子工單的生產工單" -#: build/models.py:691 +#: build/models.py:702 msgid "Cannot complete build order with incomplete outputs" msgstr "無法完成有未完成產出的生產工單" -#: build/models.py:710 build/models.py:840 +#: build/models.py:721 build/models.py:851 msgid "Failed to offload task to complete build allocations" msgstr "未能卸載任務以完成生產分配" -#: build/models.py:733 +#: build/models.py:744 #, python-brace-format msgid "Build order {build} has been completed" msgstr "生產工單 {build} 已經完成" -#: build/models.py:739 +#: build/models.py:750 msgid "A build order has been completed" msgstr "一張生產工單已經完成" -#: build/models.py:921 build/serializers.py:397 +#: build/models.py:932 build/serializers.py:403 msgid "Serial numbers must be provided for trackable parts" msgstr "對於可跟蹤的零件,必須提供序列號" -#: build/models.py:1013 build/models.py:1100 +#: build/models.py:1024 build/models.py:1113 msgid "No build output specified" msgstr "未指定產出" -#: build/models.py:1016 +#: build/models.py:1027 msgid "Build output is already completed" msgstr "產出已完成" -#: build/models.py:1019 +#: build/models.py:1030 msgid "Build output does not match Build Order" msgstr "產出與生產訂單不匹配" -#: build/models.py:1107 build/models.py:1213 build/serializers.py:275 -#: build/serializers.py:325 build/serializers.py:955 build/serializers.py:1739 -#: order/models.py:720 order/serializers.py:602 order/serializers.py:802 -#: part/serializers.py:1660 stock/models.py:945 stock/models.py:1435 -#: stock/models.py:1900 stock/serializers.py:692 stock/serializers.py:1611 +#: 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 msgid "Quantity must be greater than zero" msgstr "數量必須大於零" -#: build/models.py:1111 build/models.py:1218 build/serializers.py:280 +#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 msgid "Quantity cannot be greater than the output quantity" msgstr "數量不能大於輸出數量" -#: build/models.py:1186 build/serializers.py:596 +#: build/models.py:1199 build/serializers.py:602 msgid "Build output has not passed all required tests" msgstr "此產出尚未通過所有必要測試" -#: build/models.py:1189 build/serializers.py:591 +#: 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:1200 +#: build/models.py:1213 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "已分配的庫存項目仍在生產中" -#: build/models.py:1208 +#: build/models.py:1221 msgid "Cannot partially complete a build output with allocated items" -msgstr "" +msgstr "無法部分完成具有已分配項目的生產產出" -#: build/models.py:1737 +#: build/models.py:1750 msgid "Build Order Line Item" msgstr "生產訂單行項目" -#: build/models.py:1761 +#: build/models.py:1775 msgid "Build object" msgstr "生產對象" -#: build/models.py:1773 build/models.py:2098 build/serializers.py:261 -#: build/serializers.py:310 build/serializers.py:1447 common/models.py:1361 -#: order/models.py:1759 order/models.py:2599 order/serializers.py:1692 -#: order/serializers.py:2128 part/models.py:3480 part/models.py:3992 +#: 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 #: 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 @@ -1029,449 +1017,445 @@ 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:680 +#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "數量" -#: build/models.py:1774 +#: build/models.py:1788 msgid "Required quantity for build order" msgstr "生產工單所需數量" -#: build/models.py:1783 +#: build/models.py:1797 msgid "Quantity of consumed stock" msgstr "已消耗庫存數量" -#: build/models.py:1884 +#: build/models.py:1898 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "生產項必須指定產出,因為主零件已經被標記為可追蹤的" -#: build/models.py:1947 +#: build/models.py:1961 msgid "Selected stock item does not match BOM line" msgstr "選擇的庫存品項和BOM的項目不符" -#: build/models.py:1966 +#: build/models.py:1980 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "分配數量必須大於零" -#: build/models.py:1972 +#: build/models.py:1986 msgid "Quantity must be 1 for serialized stock" msgstr "有序號的品項數量必須為1" -#: build/models.py:1982 +#: build/models.py:1996 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "分配的數量({q})不能超過可用的庫存數量({a})" -#: build/models.py:1999 order/models.py:2548 +#: build/models.py:2013 order/models.py:2627 msgid "Stock item is over-allocated" msgstr "庫存品項超額分配" -#: build/models.py:2088 build/serializers.py:938 build/serializers.py:1244 -#: order/serializers.py:1529 order/serializers.py:1550 +#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 +#: order/serializers.py:1621 order/serializers.py:1642 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1409 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:804 stock/serializers.py:1305 stock/serializers.py:1417 +#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 +#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 msgid "Stock Item" msgstr "庫存品項" -#: build/models.py:2089 +#: build/models.py:2103 msgid "Source stock item" msgstr "來源庫存項目" -#: build/models.py:2099 +#: build/models.py:2113 msgid "Stock quantity to allocate to build" msgstr "要分配的庫存數量" -#: build/models.py:2108 +#: build/models.py:2122 msgid "Install into" msgstr "安裝到" -#: build/models.py:2109 +#: build/models.py:2123 msgid "Destination stock item" msgstr "目的庫存品項" -#: build/serializers.py:118 +#: build/serializers.py:116 msgid "Build Level" msgstr "構建等級" -#: build/serializers.py:131 part/serializers.py:1238 +#: build/serializers.py:130 part/serializers.py:1272 msgid "Part Name" msgstr "零件名稱" -#: build/serializers.py:209 build/serializers.py:964 +#: build/serializers.py:215 build/serializers.py:970 msgid "Build Output" msgstr "產出" -#: build/serializers.py:221 +#: build/serializers.py:227 msgid "Build output does not match the parent build" msgstr "產出與之前的生產不匹配" -#: build/serializers.py:225 +#: build/serializers.py:231 msgid "Output part does not match BuildOrder part" msgstr "產出零件與生產訂單零件不匹配" -#: build/serializers.py:229 +#: build/serializers.py:235 msgid "This build output has already been completed" msgstr "此產出已經完成" -#: build/serializers.py:243 +#: build/serializers.py:249 msgid "This build output is not fully allocated" msgstr "此產出尚未完全分配" -#: build/serializers.py:262 build/serializers.py:311 +#: build/serializers.py:268 build/serializers.py:317 msgid "Enter quantity for build output" msgstr "輸入產出數量" -#: build/serializers.py:333 +#: build/serializers.py:339 msgid "Integer quantity required for trackable parts" msgstr "可追蹤的零件數量必須為整數" -#: build/serializers.py:339 +#: build/serializers.py:345 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "因為BOM包含可追蹤的零件,所以數量必須為整數" -#: build/serializers.py:356 order/serializers.py:823 order/serializers.py:1696 -#: stock/serializers.py:703 +#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 +#: stock/serializers.py:728 msgid "Serial Numbers" msgstr "序號" -#: build/serializers.py:357 +#: build/serializers.py:363 msgid "Enter serial numbers for build outputs" msgstr "輸出產出的序列號" -#: build/serializers.py:363 +#: build/serializers.py:369 msgid "Stock location for build output" msgstr "生產輸出的庫存地點" -#: build/serializers.py:378 +#: build/serializers.py:384 msgid "Auto Allocate Serial Numbers" msgstr "自動分配序號" -#: build/serializers.py:380 +#: build/serializers.py:386 msgid "Automatically allocate required items with matching serial numbers" msgstr "自動為需要項目分配對應的序號" -#: build/serializers.py:413 order/serializers.py:909 stock/api.py:1183 -#: stock/models.py:1923 +#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 +#: stock/models.py:1949 msgid "The following serial numbers already exist or are invalid" msgstr "序號已存在或無效" -#: build/serializers.py:455 build/serializers.py:511 build/serializers.py:603 +#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 msgid "A list of build outputs must be provided" msgstr "必須提供產出清單" -#: build/serializers.py:488 +#: build/serializers.py:494 msgid "Stock location for scrapped outputs" msgstr "廢品產出的庫存位置" -#: build/serializers.py:494 +#: build/serializers.py:500 msgid "Discard Allocations" msgstr "放棄分配" -#: build/serializers.py:495 +#: build/serializers.py:501 msgid "Discard any stock allocations for scrapped outputs" msgstr "取消對廢品產出的任何庫存分配" -#: build/serializers.py:500 +#: build/serializers.py:506 msgid "Reason for scrapping build output(s)" msgstr "廢品產出的原因" -#: build/serializers.py:558 +#: build/serializers.py:564 msgid "Location for completed build outputs" msgstr "已完成刪除的庫存地點" -#: build/serializers.py:566 +#: build/serializers.py:572 msgid "Accept Incomplete Allocation" msgstr "接受不完整的分配" -#: build/serializers.py:567 +#: build/serializers.py:573 msgid "Complete outputs if stock has not been fully allocated" msgstr "如果庫存尚未全部分配,則完成產出" -#: build/serializers.py:692 +#: build/serializers.py:698 msgid "Consume Allocated Stock" msgstr "消費已分配的庫存" -#: build/serializers.py:693 +#: build/serializers.py:699 msgid "Consume any stock which has already been allocated to this build" msgstr "消耗已分配給此生產的任何庫存" -#: build/serializers.py:699 +#: build/serializers.py:705 msgid "Remove Incomplete Outputs" msgstr "移除未完成的產出" -#: build/serializers.py:700 +#: build/serializers.py:706 msgid "Delete any build outputs which have not been completed" msgstr "刪除所有未完成的產出" -#: build/serializers.py:727 +#: build/serializers.py:733 msgid "Not permitted" msgstr "不允許" -#: build/serializers.py:728 +#: build/serializers.py:734 msgid "Accept as consumed by this build order" msgstr "接受作為此生產訂單的消費" -#: build/serializers.py:729 +#: build/serializers.py:735 msgid "Deallocate before completing this build order" msgstr "完成此生產訂單前取消分配" -#: build/serializers.py:756 +#: build/serializers.py:762 msgid "Overallocated Stock" msgstr "超出分配的庫存" -#: build/serializers.py:759 +#: build/serializers.py:765 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "如何處理分配給生產訂單的額外庫存項" -#: build/serializers.py:770 +#: build/serializers.py:776 msgid "Some stock items have been overallocated" msgstr "有庫存項目已被過度分配" -#: build/serializers.py:775 +#: build/serializers.py:781 msgid "Accept Unallocated" msgstr "接受未分配" -#: build/serializers.py:777 +#: build/serializers.py:783 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "接受庫存項未被完全分配至生產訂單" -#: build/serializers.py:788 +#: build/serializers.py:794 msgid "Required stock has not been fully allocated" msgstr "所需庫存尚未完全分配" -#: build/serializers.py:793 order/serializers.py:478 order/serializers.py:1597 +#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 msgid "Accept Incomplete" msgstr "接受不完整" -#: build/serializers.py:795 +#: build/serializers.py:801 msgid "Accept that the required number of build outputs have not been completed" msgstr "允許所需數量的產出未完成" -#: build/serializers.py:806 +#: build/serializers.py:812 msgid "Required build quantity has not been completed" msgstr "未完成所需生產數量" -#: build/serializers.py:818 +#: build/serializers.py:824 msgid "Build order has open child build orders" msgstr "生產訂單有打開的子生產訂單" -#: build/serializers.py:821 +#: build/serializers.py:827 msgid "Build order must be in production state" msgstr "生產訂單必須處於生產狀態" -#: build/serializers.py:824 +#: build/serializers.py:830 msgid "Build order has incomplete outputs" msgstr "生產訂單有未完成的產出" -#: build/serializers.py:863 +#: build/serializers.py:869 msgid "Build Line" msgstr "生產行" -#: build/serializers.py:871 +#: build/serializers.py:877 msgid "Build output" msgstr "產出" -#: build/serializers.py:879 +#: build/serializers.py:885 msgid "Build output must point to the same build" msgstr "生產產出必須指向相同的生產" -#: build/serializers.py:910 +#: build/serializers.py:916 msgid "Build Line Item" msgstr "生產行項目" -#: build/serializers.py:928 +#: build/serializers.py:934 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part 必須與生產訂單零件相同" -#: build/serializers.py:944 stock/serializers.py:1318 +#: build/serializers.py:950 stock/serializers.py:1362 msgid "Item must be in stock" msgstr "商品必須有庫存" -#: build/serializers.py:987 order/serializers.py:1583 +#: build/serializers.py:993 order/serializers.py:1684 #, python-brace-format msgid "Available quantity ({q}) exceeded" msgstr "可用量 ({q}) 超出限制" -#: build/serializers.py:993 +#: build/serializers.py:999 msgid "Build output must be specified for allocation of tracked parts" msgstr "對於被追蹤的零件的分配,必須指定生產產出" -#: build/serializers.py:1001 +#: build/serializers.py:1007 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "對於未被追蹤的零件,無法指定生產產出" -#: build/serializers.py:1025 order/serializers.py:1856 +#: build/serializers.py:1031 order/serializers.py:1967 msgid "Allocation items must be provided" msgstr "必須提供分配項目" -#: build/serializers.py:1089 +#: build/serializers.py:1095 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "零件來源的庫存地點(留空則可來源於任何庫存地點)" -#: build/serializers.py:1098 +#: build/serializers.py:1104 msgid "Exclude Location" msgstr "排除位置" -#: build/serializers.py:1099 +#: build/serializers.py:1105 msgid "Exclude stock items from this selected location" msgstr "從該選定的庫存地點排除庫存項" -#: build/serializers.py:1104 +#: build/serializers.py:1110 msgid "Interchangeable Stock" msgstr "可互換庫存" -#: build/serializers.py:1105 +#: build/serializers.py:1111 msgid "Stock items in multiple locations can be used interchangeably" msgstr "在多個位置的庫存項目可以互換使用" -#: build/serializers.py:1110 +#: build/serializers.py:1116 msgid "Substitute Stock" msgstr "替代品庫存" -#: build/serializers.py:1111 +#: build/serializers.py:1117 msgid "Allow allocation of substitute parts" msgstr "允許分配可替換的零件" -#: build/serializers.py:1116 +#: build/serializers.py:1122 msgid "Optional Items" msgstr "可選項目" -#: build/serializers.py:1117 +#: build/serializers.py:1123 msgid "Allocate optional BOM items to build order" msgstr "分配可選的物料清單給生產訂單" -#: build/serializers.py:1123 +#: build/serializers.py:1129 msgid "All Items" -msgstr "" +msgstr "全部品項" -#: build/serializers.py:1124 +#: build/serializers.py:1130 msgid "Untracked Items" -msgstr "" +msgstr "未追蹤項目" -#: build/serializers.py:1125 +#: build/serializers.py:1131 msgid "Tracked Items" -msgstr "" +msgstr "已追蹤項目" -#: build/serializers.py:1127 +#: build/serializers.py:1133 msgid "Item Type" -msgstr "" +msgstr "品項類型" -#: build/serializers.py:1128 +#: build/serializers.py:1134 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "選擇要自動分配的項目類型" -#: build/serializers.py:1150 -msgid "Failed to start auto-allocation task" -msgstr "啓動自動分配任務失敗" - -#: build/serializers.py:1203 +#: build/serializers.py:1188 msgid "BOM Reference" msgstr "物料清單參考" -#: build/serializers.py:1209 +#: build/serializers.py:1194 msgid "BOM Part ID" msgstr "物料清單零件識別號碼" -#: build/serializers.py:1216 +#: build/serializers.py:1201 msgid "BOM Part Name" msgstr "物料清單零件名稱" -#: build/serializers.py:1265 +#: build/serializers.py:1253 msgid "Install Into" -msgstr "" +msgstr "安裝至" -#: build/serializers.py:1292 build/serializers.py:1510 +#: build/serializers.py:1282 build/serializers.py:1511 msgid "Build" msgstr "生產" -#: build/serializers.py:1311 company/models.py:633 order/api.py:316 -#: order/api.py:321 order/api.py:547 order/serializers.py:594 -#: stock/models.py:1041 stock/serializers.py:571 +#: 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 msgid "Supplier Part" msgstr "供應商零件" -#: build/serializers.py:1327 stock/serializers.py:624 +#: build/serializers.py:1318 stock/serializers.py:649 msgid "Allocated Quantity" msgstr "已分配數量" -#: build/serializers.py:1394 +#: build/serializers.py:1385 msgid "Build Reference" msgstr "構建參考" -#: build/serializers.py:1404 +#: build/serializers.py:1395 msgid "Part Category Name" msgstr "零件類別名稱" -#: build/serializers.py:1438 common/setting/system.py:494 part/models.py:1265 +#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 msgid "Trackable" msgstr "可追蹤" -#: build/serializers.py:1441 +#: build/serializers.py:1436 msgid "Inherited" msgstr "已繼承的" -#: build/serializers.py:1444 part/models.py:4077 +#: build/serializers.py:1439 part/models.py:4154 msgid "Allow Variants" msgstr "允許變體" -#: build/serializers.py:1450 build/serializers.py:1455 part/models.py:3798 -#: part/models.py:4381 stock/api.py:882 +#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 +#: part/models.py:4458 stock/api.py:881 msgid "BOM Item" msgstr "物料清單項" -#: build/serializers.py:1528 order/serializers.py:1271 part/serializers.py:1156 -#: part/serializers.py:1725 +#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 +#: part/serializers.py:1773 msgid "In Production" msgstr "生產中" -#: build/serializers.py:1530 part/serializers.py:822 part/serializers.py:1160 +#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 msgid "Scheduled to Build" msgstr "排程生產中" -#: build/serializers.py:1533 part/serializers.py:855 +#: build/serializers.py:1534 part/serializers.py:882 msgid "External Stock" msgstr "外部庫存" -#: build/serializers.py:1534 part/serializers.py:1146 part/serializers.py:1768 +#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 msgid "Available Stock" msgstr "可用庫存" -#: build/serializers.py:1536 +#: build/serializers.py:1537 msgid "Available Substitute Stock" msgstr "可用的替代品庫存" -#: build/serializers.py:1539 +#: build/serializers.py:1540 msgid "Available Variant Stock" msgstr "可用的變體庫存" -#: build/serializers.py:1752 +#: build/serializers.py:1753 msgid "Consumed quantity exceeds allocated quantity" msgstr "消耗數量超過已分配數量" -#: build/serializers.py:1789 +#: build/serializers.py:1790 msgid "Optional notes for the stock consumption" msgstr "庫存耗用的可選備註" -#: build/serializers.py:1806 +#: build/serializers.py:1807 msgid "Build item must point to the correct build order" msgstr "生產項必須指向正確的生產工單" -#: build/serializers.py:1811 +#: build/serializers.py:1812 msgid "Duplicate build item allocation" msgstr "重複的生產項分配" -#: build/serializers.py:1829 +#: build/serializers.py:1830 msgid "Build line must point to the correct build order" msgstr "生產行必須指向正確的生產工單" -#: build/serializers.py:1834 +#: build/serializers.py:1835 msgid "Duplicate build line allocation" msgstr "重複的生產行分配" -#: build/serializers.py:1846 +#: build/serializers.py:1847 msgid "At least one item or line must be provided" msgstr "至少必須提供一個項目或一行" @@ -1495,43 +1479,47 @@ msgstr "被掛起" msgid "Cancelled" msgstr "已取消" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:574 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 #: importer/status_codes.py:27 order/status_codes.py:15 #: order/status_codes.py:52 order/status_codes.py:83 msgid "Complete" msgstr "完成" -#: build/tasks.py:231 +#: build/tasks.py:218 msgid "Stock required for build order" msgstr "生產訂單所需庫存" -#: build/tasks.py:241 +#: build/tasks.py:228 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "生產工單 {build} 需要額外庫存" -#: build/tasks.py:265 +#: build/tasks.py:252 msgid "Overdue Build Order" msgstr "逾期的生產訂單" -#: build/tasks.py:270 +#: build/tasks.py:257 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "生產訂單 {bo} 現已逾期" -#: common/api.py:711 +#: common/api.py:722 msgid "Is Link" msgstr "是否鏈接" -#: common/api.py:719 +#: common/api.py:730 msgid "Is File" msgstr "是否為文件" -#: common/api.py:766 +#: common/api.py:777 msgid "User does not have permission to delete these attachments" msgstr "用户沒有權限刪除此附件" -#: common/api.py:779 +#: common/api.py:790 +msgid "User does not have permission to edit this attachment" +msgstr "" + +#: common/api.py:816 msgid "User does not have permission to delete this attachment" msgstr "用户沒有權限刪除此附件" @@ -1551,798 +1539,822 @@ msgstr "未提供有效的貨幣代碼" msgid "No plugin" msgstr "暫無插件" -#: common/filters.py:351 +#: common/filters.py:359 msgid "Project Code Label" msgstr "項目編碼標籤" -#: common/models.py:105 common/models.py:130 common/models.py:3169 +#: common/models.py:108 common/models.py:133 common/models.py:3279 msgid "Updated" msgstr "已是最新" -#: common/models.py:106 common/models.py:131 +#: common/models.py:109 common/models.py:134 order/models.py:507 msgid "Timestamp of last update" msgstr "最後更新時間戳" -#: common/models.py:143 +#: common/models.py:146 msgid "Update By" msgstr "更新者" -#: common/models.py:144 +#: common/models.py:147 msgid "User who last updated this object" msgstr "最後更新此物件的使用者" -#: common/models.py:171 +#: common/models.py:174 msgid "Unique project code" msgstr "唯一項目編碼" -#: common/models.py:178 +#: common/models.py:181 msgid "Project description" msgstr "項目描述" -#: common/models.py:187 +#: common/models.py:190 msgid "User or group responsible for this project" msgstr "負責此項目的用户或羣組" -#: common/models.py:777 common/models.py:1293 common/models.py:1331 +#: common/models.py:789 common/models.py:1305 common/models.py:1343 msgid "Settings key" msgstr "設定鍵值" -#: common/models.py:781 +#: common/models.py:793 msgid "Settings value" msgstr "設定值" -#: common/models.py:836 +#: common/models.py:848 msgid "Chosen value is not a valid option" msgstr "所選值不是一個有效的選項" -#: common/models.py:852 +#: common/models.py:864 msgid "Value must be a boolean value" msgstr "該值必須是布爾值" -#: common/models.py:860 +#: common/models.py:872 msgid "Value must be an integer value" msgstr "該值必須為整數" -#: common/models.py:868 +#: common/models.py:880 msgid "Value must be a valid number" msgstr "值必須為有效數字" -#: common/models.py:893 +#: common/models.py:905 msgid "Value does not pass validation checks" msgstr "值未通過驗證檢查" -#: common/models.py:915 +#: common/models.py:927 msgid "Key string must be unique" msgstr "鍵字符串必須是唯一的" -#: common/models.py:1339 common/models.py:1340 common/models.py:1444 -#: common/models.py:1445 common/models.py:1690 common/models.py:1691 -#: common/models.py:2023 common/models.py:2024 common/models.py:2822 -#: importer/models.py:101 part/models.py:3574 part/models.py:3602 +#: 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:501 +#: users/models.py:499 msgid "User" msgstr "使用者" -#: common/models.py:1362 +#: common/models.py:1374 msgid "Price break quantity" msgstr "批發價數量" -#: common/models.py:1369 company/serializers.py:316 order/models.py:1845 -#: order/models.py:3050 +#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 +#: order/models.py:3131 msgid "Price" msgstr "價格" -#: common/models.py:1370 +#: common/models.py:1382 msgid "Unit price at specified quantity" msgstr "指定數量的單位價格" -#: common/models.py:1421 common/models.py:1606 +#: common/models.py:1433 common/models.py:1618 msgid "Endpoint" msgstr "端點" -#: common/models.py:1422 +#: common/models.py:1434 msgid "Endpoint at which this webhook is received" msgstr "接收此網絡鈎子的端點" -#: common/models.py:1432 +#: common/models.py:1444 msgid "Name for this webhook" msgstr "此網絡鈎子的名稱" -#: common/models.py:1436 common/models.py:2264 common/models.py:2371 -#: company/models.py:193 company/models.py:781 machine/models.py:40 -#: part/models.py:1288 plugin/models.py:69 stock/api.py:642 users/models.py:195 -#: users/models.py:554 users/serializers.py:319 +#: 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 msgid "Active" msgstr "激活" -#: common/models.py:1436 +#: common/models.py:1448 msgid "Is this webhook active" msgstr "網絡鈎子是否已啓用" -#: common/models.py:1452 users/models.py:172 +#: common/models.py:1464 users/models.py:172 msgid "Token" msgstr "令牌" -#: common/models.py:1453 +#: common/models.py:1465 msgid "Token for access" msgstr "訪問令牌" -#: common/models.py:1461 +#: common/models.py:1473 msgid "Secret" msgstr "密鑰" -#: common/models.py:1462 +#: common/models.py:1474 msgid "Shared secret for HMAC" msgstr "HMAC共享密鑰" -#: common/models.py:1570 common/models.py:3059 +#: common/models.py:1582 common/models.py:3169 msgid "Message ID" msgstr "消息ID" -#: common/models.py:1571 common/models.py:3049 +#: common/models.py:1583 common/models.py:3159 msgid "Unique identifier for this message" msgstr "此郵件的唯一標識符" -#: common/models.py:1579 +#: common/models.py:1591 msgid "Host" msgstr "主機" -#: common/models.py:1580 +#: common/models.py:1592 msgid "Host from which this message was received" msgstr "接收此消息的主機" -#: common/models.py:1588 +#: common/models.py:1600 msgid "Header" msgstr "標題" -#: common/models.py:1589 +#: common/models.py:1601 msgid "Header of this message" msgstr "此消息的標題" -#: common/models.py:1596 +#: common/models.py:1608 msgid "Body" msgstr "正文" -#: common/models.py:1597 +#: common/models.py:1609 msgid "Body of this message" msgstr "此消息的正文" -#: common/models.py:1607 +#: common/models.py:1619 msgid "Endpoint on which this message was received" msgstr "接收此消息的終點" -#: common/models.py:1612 +#: common/models.py:1624 msgid "Worked on" msgstr "工作於" -#: common/models.py:1613 +#: common/models.py:1625 msgid "Was the work on this message finished?" msgstr "這條消息的工作完成了嗎?" -#: common/models.py:1739 +#: common/models.py:1751 msgid "Id" msgstr "標識" -#: common/models.py:1741 +#: common/models.py:1753 msgid "Title" msgstr "標題" -#: common/models.py:1743 common/models.py:2006 company/models.py:187 -#: company/models.py:474 company/models.py:544 company/models.py:804 -#: order/models.py:460 order/models.py:1789 order/models.py:2345 -#: part/models.py:1181 +#: 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 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "連結" -#: common/models.py:1745 +#: common/models.py:1757 msgid "Published" msgstr "已發佈" -#: common/models.py:1747 +#: common/models.py:1759 msgid "Author" msgstr "作者" -#: common/models.py:1749 +#: common/models.py:1761 msgid "Summary" msgstr "摘要" -#: common/models.py:1752 common/models.py:3026 +#: common/models.py:1764 common/models.py:3136 msgid "Read" msgstr "閲讀" -#: common/models.py:1752 +#: common/models.py:1764 msgid "Was this news item read?" msgstr "這條新聞被閲讀了嗎?" -#: common/models.py:1769 +#: common/models.py:1781 msgid "Image file" msgstr "圖像文件" -#: common/models.py:1781 +#: common/models.py:1793 msgid "Target model type for this image" msgstr "此圖像的目標模型類型" -#: common/models.py:1785 +#: common/models.py:1797 msgid "Target model ID for this image" msgstr "此圖像的目標型號ID" -#: common/models.py:1807 +#: common/models.py:1819 msgid "Custom Unit" msgstr "自定義單位" -#: common/models.py:1825 +#: common/models.py:1837 msgid "Unit symbol must be unique" msgstr "單位符號必須唯一" -#: common/models.py:1840 +#: common/models.py:1852 msgid "Unit name must be a valid identifier" msgstr "單位名稱必須是有效的標識符" -#: common/models.py:1859 +#: common/models.py:1871 msgid "Unit name" msgstr "單位名稱" -#: common/models.py:1866 +#: common/models.py:1878 msgid "Symbol" msgstr "符號" -#: common/models.py:1867 +#: common/models.py:1879 msgid "Optional unit symbol" msgstr "可選單位符號" -#: common/models.py:1873 +#: common/models.py:1885 msgid "Definition" msgstr "定義" -#: common/models.py:1874 +#: common/models.py:1886 msgid "Unit definition" msgstr "單位定義" -#: common/models.py:1934 common/models.py:1997 stock/models.py:3071 -#: stock/serializers.py:249 +#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 +#: stock/serializers.py:258 msgid "Attachment" msgstr "附件" -#: common/models.py:1951 +#: common/models.py:1979 msgid "Missing file" msgstr "缺少檔案" -#: common/models.py:1952 +#: common/models.py:1980 msgid "Missing external link" msgstr "缺少外部連結" -#: common/models.py:1989 common/models.py:2507 +#: common/models.py:2019 +msgid "No file attached to rename" +msgstr "" + +#: common/models.py:2022 +msgid "Filename cannot be empty" +msgstr "" + +#: common/models.py:2027 common/models.py:2047 +msgid "Invalid filename" +msgstr "" + +#: common/models.py:2033 +msgid "Cannot change file extension" +msgstr "" + +#: common/models.py:2052 +msgid "A file with this name already exists" +msgstr "" + +#: common/models.py:2059 +msgid "Failed to save renamed file" +msgstr "" + +#: common/models.py:2071 common/models.py:2617 msgid "Model type" msgstr "模型類型" -#: common/models.py:1990 +#: common/models.py:2072 msgid "Target model type for image" msgstr "圖像的目標模型類型" -#: common/models.py:1998 +#: common/models.py:2080 msgid "Select file to attach" msgstr "選擇附件" -#: common/models.py:2014 +#: common/models.py:2096 msgid "Comment" msgstr "註解" -#: common/models.py:2015 +#: common/models.py:2097 msgid "Attachment comment" msgstr "附件評論" -#: common/models.py:2031 +#: common/models.py:2113 msgid "Upload date" msgstr "上傳日期" -#: common/models.py:2032 +#: common/models.py:2114 msgid "Date the file was uploaded" msgstr "上傳文件的日期" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size" msgstr "文件大小" -#: common/models.py:2036 +#: common/models.py:2118 msgid "File size in bytes" msgstr "文件大小,以字節為單位" -#: common/models.py:2074 common/serializers.py:715 +#: common/models.py:2156 common/serializers.py:796 msgid "Invalid model type specified for attachment" msgstr "為附件指定的模型類型無效" -#: common/models.py:2095 +#: common/models.py:2177 msgid "Custom State" msgstr "自定狀態" -#: common/models.py:2096 +#: common/models.py:2178 msgid "Custom States" msgstr "定製狀態" -#: common/models.py:2101 +#: common/models.py:2183 msgid "Reference Status Set" msgstr "參考狀態設定" -#: common/models.py:2102 +#: common/models.py:2184 msgid "Status set that is extended with this custom state" msgstr "使用此自定義狀態擴展狀態的狀態集" -#: common/models.py:2106 generic/states/serializers.py:18 +#: common/models.py:2188 generic/states/serializers.py:18 msgid "Logical Key" msgstr "邏輯密鑰" -#: common/models.py:2108 +#: common/models.py:2190 msgid "State logical key that is equal to this custom state in business logic" msgstr "等同於商業邏輯中自定義狀態的狀態邏輯鍵" -#: common/models.py:2113 common/models.py:2352 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3063 +#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 msgid "Value" msgstr "值" -#: common/models.py:2114 +#: common/models.py:2196 msgid "Numerical value that will be saved in the models database" msgstr "將儲存於模型資料庫中的數值" -#: common/models.py:2120 +#: common/models.py:2202 msgid "Name of the state" msgstr "狀態名" -#: common/models.py:2129 common/models.py:2358 generic/states/serializers.py:22 +#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 msgid "Label" msgstr "標籤" -#: common/models.py:2130 +#: common/models.py:2212 msgid "Label that will be displayed in the frontend" msgstr "在前端顯示的標籤" -#: common/models.py:2137 generic/states/serializers.py:24 +#: common/models.py:2219 generic/states/serializers.py:24 msgid "Color" msgstr "顏色" -#: common/models.py:2138 +#: common/models.py:2220 msgid "Color that will be displayed in the frontend" msgstr "將在前端顯示顏色" -#: common/models.py:2146 +#: common/models.py:2228 msgid "Model" msgstr "模式" -#: common/models.py:2147 +#: common/models.py:2229 msgid "Model this state is associated with" msgstr "該狀態關聯的模型" -#: common/models.py:2162 +#: common/models.py:2244 msgid "Model must be selected" msgstr "必須選定模型" -#: common/models.py:2165 +#: common/models.py:2247 msgid "Key must be selected" msgstr "必須選取密鑰" -#: common/models.py:2168 +#: common/models.py:2250 msgid "Logical key must be selected" msgstr "必須選中邏輯密鑰" -#: common/models.py:2172 +#: common/models.py:2254 msgid "Key must be different from logical key" msgstr "密鑰必須不同於邏輯密鑰" -#: common/models.py:2179 +#: common/models.py:2261 msgid "Valid reference status class must be provided" msgstr "必須提供有效參考狀態類別" -#: common/models.py:2185 +#: common/models.py:2267 msgid "Key must be different from the logical keys of the reference status" msgstr "密鑰必須不同於參考狀態的邏輯密鑰" -#: common/models.py:2192 +#: common/models.py:2274 msgid "Logical key must be in the logical keys of the reference status" msgstr "邏輯密鑰必須在參考狀態的邏輯鍵中" -#: common/models.py:2199 +#: common/models.py:2281 msgid "Name must be different from the names of the reference status" msgstr "名稱必須不同於參考狀態的名稱" -#: common/models.py:2239 common/models.py:2346 common/models.py:2552 +#: common/models.py:2321 common/models.py:2456 common/models.py:2662 msgid "Selection List" msgstr "選擇列表" -#: common/models.py:2240 +#: common/models.py:2322 msgid "Selection Lists" msgstr "選擇列表" -#: common/models.py:2245 +#: common/models.py:2327 msgid "Name of the selection list" msgstr "選擇列表名稱" -#: common/models.py:2252 +#: common/models.py:2334 msgid "Description of the selection list" msgstr "選擇列表描述" -#: common/models.py:2258 part/models.py:1293 +#: common/models.py:2340 part/models.py:1297 msgid "Locked" msgstr "已鎖定" -#: common/models.py:2259 +#: common/models.py:2341 msgid "Is this selection list locked?" msgstr "此選擇列表是否已鎖定?" -#: common/models.py:2265 +#: common/models.py:2347 msgid "Can this selection list be used?" msgstr "此選擇列表是否可使用?" -#: common/models.py:2273 +#: common/models.py:2355 msgid "Source Plugin" msgstr "來源模組" -#: common/models.py:2274 +#: common/models.py:2356 msgid "Plugin which provides the selection list" msgstr "提供此選擇列表的模組" -#: common/models.py:2279 +#: common/models.py:2361 msgid "Source String" msgstr "來源字串" -#: common/models.py:2280 +#: common/models.py:2362 msgid "Optional string identifying the source used for this list" msgstr "用於標示此列表來源的可選字串" -#: common/models.py:2289 +#: common/models.py:2371 msgid "Default Entry" msgstr "預設項目" -#: common/models.py:2290 +#: common/models.py:2372 msgid "Default entry for this selection list" msgstr "此選擇列表的預設項目" -#: common/models.py:2295 common/models.py:3164 +#: common/models.py:2377 common/models.py:3274 msgid "Created" msgstr "已創建" -#: common/models.py:2296 +#: common/models.py:2378 msgid "Date and time that the selection list was created" msgstr "選擇列表建立的日期與時間" -#: common/models.py:2301 +#: common/models.py:2383 msgid "Last Updated" msgstr "最近更新" -#: common/models.py:2302 +#: common/models.py:2384 msgid "Date and time that the selection list was last updated" msgstr "選擇列表最近更新的日期與時間" -#: common/models.py:2336 +#: common/models.py:2446 msgid "Selection List Entry" msgstr "選擇列表項目" -#: common/models.py:2337 +#: common/models.py:2447 msgid "Selection List Entries" msgstr "選擇列表項目" -#: common/models.py:2347 +#: common/models.py:2457 msgid "Selection list to which this entry belongs" msgstr "該項目所屬的選擇列表" -#: common/models.py:2353 +#: common/models.py:2463 msgid "Value of the selection list entry" msgstr "選擇列表項目的值" -#: common/models.py:2359 +#: common/models.py:2469 msgid "Label for the selection list entry" msgstr "選擇列表項目的標籤" -#: common/models.py:2365 +#: common/models.py:2475 msgid "Description of the selection list entry" msgstr "選擇列表項目的描述" -#: common/models.py:2372 +#: common/models.py:2482 msgid "Is this selection list entry active?" msgstr "此選擇列表項目是否啟用?" -#: common/models.py:2406 +#: common/models.py:2516 msgid "Parameter Template" msgstr "參數模板" -#: common/models.py:2407 +#: common/models.py:2517 msgid "Parameter Templates" -msgstr "" +msgstr "參數範本" -#: common/models.py:2444 +#: common/models.py:2554 msgid "Checkbox parameters cannot have units" msgstr "勾選框參數不能有單位" -#: common/models.py:2449 +#: common/models.py:2559 msgid "Checkbox parameters cannot have choices" msgstr "複選框參數不能有選項" -#: common/models.py:2469 part/models.py:3672 +#: common/models.py:2579 part/models.py:3686 msgid "Choices must be unique" msgstr "選擇必須是唯一的" -#: common/models.py:2486 +#: common/models.py:2596 msgid "Parameter template name must be unique" msgstr "參數模板名稱必須是唯一的" -#: common/models.py:2508 +#: common/models.py:2618 msgid "Target model type for this parameter template" -msgstr "" +msgstr "此參數範本的目標模型類型" -#: common/models.py:2514 +#: common/models.py:2624 msgid "Parameter Name" msgstr "參數名稱" -#: common/models.py:2520 part/models.py:1246 +#: common/models.py:2630 part/models.py:1250 msgid "Units" msgstr "單位" -#: common/models.py:2521 +#: common/models.py:2631 msgid "Physical units for this parameter" msgstr "此參數的物理單位" -#: common/models.py:2529 +#: common/models.py:2639 msgid "Parameter description" msgstr "參數説明" -#: common/models.py:2535 +#: common/models.py:2645 msgid "Checkbox" msgstr "勾選框" -#: common/models.py:2536 +#: common/models.py:2646 msgid "Is this parameter a checkbox?" msgstr "此參數是否為勾選框?" -#: common/models.py:2541 part/models.py:3759 +#: common/models.py:2651 part/models.py:3773 msgid "Choices" msgstr "選項" -#: common/models.py:2542 +#: common/models.py:2652 msgid "Valid choices for this parameter (comma-separated)" msgstr "此參數的有效選擇 (逗號分隔)" -#: common/models.py:2553 +#: common/models.py:2663 msgid "Selection list for this parameter" msgstr "此參數的選擇清單" -#: common/models.py:2558 part/models.py:3734 report/models.py:287 +#: common/models.py:2668 part/models.py:3748 report/models.py:292 msgid "Enabled" msgstr "已啓用" -#: common/models.py:2559 +#: common/models.py:2669 msgid "Is this parameter template enabled?" -msgstr "" +msgstr "是否啟用此參數範本?" -#: common/models.py:2600 +#: common/models.py:2710 msgid "Parameter" -msgstr "" +msgstr "參數" -#: common/models.py:2601 +#: common/models.py:2711 msgid "Parameters" -msgstr "" +msgstr "參數集" -#: common/models.py:2647 +#: common/models.py:2757 msgid "Invalid choice for parameter value" msgstr "無效的參數值選擇" -#: common/models.py:2717 common/serializers.py:810 +#: common/models.py:2827 common/serializers.py:892 msgid "Invalid model type specified for parameter" -msgstr "" +msgstr "為參數指定的模型類型無效" -#: common/models.py:2753 +#: common/models.py:2863 msgid "Model ID" -msgstr "" +msgstr "模型 ID" -#: common/models.py:2754 +#: common/models.py:2864 msgid "ID of the target model for this parameter" -msgstr "" +msgstr "此參數的目標模型 ID" -#: common/models.py:2763 common/setting/system.py:464 report/models.py:373 -#: report/models.py:669 report/serializers.py:94 report/serializers.py:135 -#: stock/serializers.py:235 +#: 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 msgid "Template" msgstr "模板" -#: common/models.py:2764 +#: common/models.py:2874 msgid "Parameter template" -msgstr "" +msgstr "參數範本" -#: common/models.py:2769 common/models.py:2811 importer/models.py:568 +#: common/models.py:2879 common/models.py:2921 importer/models.py:581 msgid "Data" msgstr "數據" -#: common/models.py:2770 +#: common/models.py:2880 msgid "Parameter Value" msgstr "參數值" -#: common/models.py:2779 company/models.py:821 order/serializers.py:841 -#: order/serializers.py:2044 part/models.py:4052 part/models.py:4421 +#: common/models.py:2889 company/models.py:826 order/serializers.py:896 +#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 #: 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:817 +#: stock/serializers.py:842 msgid "Note" msgstr "備註" -#: common/models.py:2780 stock/serializers.py:722 +#: common/models.py:2890 stock/serializers.py:747 msgid "Optional note field" msgstr "可選註釋字段" -#: common/models.py:2807 +#: common/models.py:2917 msgid "Barcode Scan" msgstr "掃描條碼" -#: common/models.py:2812 +#: common/models.py:2922 msgid "Barcode data" msgstr "條碼數據" -#: common/models.py:2823 +#: common/models.py:2933 msgid "User who scanned the barcode" msgstr "掃描條碼" -#: common/models.py:2828 importer/models.py:70 +#: common/models.py:2938 importer/models.py:70 msgid "Timestamp" msgstr "時間戳" -#: common/models.py:2829 +#: common/models.py:2939 msgid "Date and time of the barcode scan" msgstr "掃描條碼的日期和時間" -#: common/models.py:2835 +#: common/models.py:2945 msgid "URL endpoint which processed the barcode" msgstr "處理條碼的 URL 終點" -#: common/models.py:2842 order/models.py:1835 plugin/serializers.py:93 +#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 msgid "Context" msgstr "上下文" -#: common/models.py:2843 +#: common/models.py:2953 msgid "Context data for the barcode scan" msgstr "掃描條碼的上下文數據" -#: common/models.py:2850 +#: common/models.py:2960 msgid "Response" msgstr "響應" -#: common/models.py:2851 +#: common/models.py:2961 msgid "Response data from the barcode scan" msgstr "掃描條碼的響應數據" -#: common/models.py:2857 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3057 +#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3083 msgid "Result" msgstr "結果" -#: common/models.py:2858 +#: common/models.py:2968 msgid "Was the barcode scan successful?" msgstr "條碼掃描成功嗎?" -#: common/models.py:2940 +#: common/models.py:3050 msgid "An error occurred" msgstr "發生錯誤" -#: common/models.py:2961 +#: common/models.py:3071 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:3008 +#: common/models.py:3118 msgid "Email Message" msgstr "電子郵件訊息" -#: common/models.py:3009 +#: common/models.py:3119 msgid "Email Messages" msgstr "電子郵件訊息" -#: common/models.py:3016 +#: common/models.py:3126 msgid "Announced" msgstr "已公告" -#: common/models.py:3018 +#: common/models.py:3128 msgid "Sent" msgstr "已發送" -#: common/models.py:3019 +#: common/models.py:3129 msgid "Failed" msgstr "失敗" -#: common/models.py:3022 +#: common/models.py:3132 msgid "Delivered" msgstr "已送達" -#: common/models.py:3030 +#: common/models.py:3140 msgid "Confirmed" msgstr "已確認" -#: common/models.py:3036 +#: common/models.py:3146 msgid "Inbound" msgstr "入站" -#: common/models.py:3037 +#: common/models.py:3147 msgid "Outbound" msgstr "出站" -#: common/models.py:3042 +#: common/models.py:3152 msgid "No Reply" msgstr "不回覆" -#: common/models.py:3043 +#: common/models.py:3153 msgid "Track Delivery" msgstr "追蹤投遞" -#: common/models.py:3044 +#: common/models.py:3154 msgid "Track Read" msgstr "追蹤已讀" -#: common/models.py:3045 +#: common/models.py:3155 msgid "Track Click" msgstr "追蹤點擊" -#: common/models.py:3048 common/models.py:3151 +#: common/models.py:3158 common/models.py:3261 msgid "Global ID" msgstr "全域 ID" -#: common/models.py:3061 +#: common/models.py:3171 msgid "Identifier for this message (might be supplied by external system)" msgstr "此訊息的識別碼(可能由外部系統提供)" -#: common/models.py:3068 +#: common/models.py:3178 msgid "Thread ID" msgstr "討論串 ID" -#: common/models.py:3070 +#: common/models.py:3180 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "此訊息討論串的識別碼(可能由外部系統提供)" -#: common/models.py:3079 +#: common/models.py:3189 msgid "Thread" msgstr "討論串" -#: common/models.py:3080 +#: common/models.py:3190 msgid "Linked thread for this message" msgstr "此訊息所連結的討論串" -#: common/models.py:3096 +#: common/models.py:3206 msgid "Priority" -msgstr "" +msgstr "優先序" -#: common/models.py:3138 +#: common/models.py:3248 msgid "Email Thread" msgstr "電子郵件討論串" -#: common/models.py:3139 +#: common/models.py:3249 msgid "Email Threads" msgstr "電子郵件討論串" -#: common/models.py:3145 generic/states/serializers.py:16 +#: common/models.py:3255 generic/states/serializers.py:16 #: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 msgid "Key" msgstr "鍵" -#: common/models.py:3148 +#: common/models.py:3258 msgid "Unique key for this thread (used to identify the thread)" msgstr "此討論串的唯一鍵(用於辨識)" -#: common/models.py:3152 +#: common/models.py:3262 msgid "Unique identifier for this thread" msgstr "此討論串的唯一識別碼" -#: common/models.py:3159 +#: common/models.py:3269 msgid "Started Internal" msgstr "內部建立" -#: common/models.py:3160 +#: common/models.py:3270 msgid "Was this thread started internally?" msgstr "此討論串是否為內部建立?" -#: common/models.py:3165 +#: common/models.py:3275 msgid "Date and time that the thread was created" msgstr "討論串建立的日期時間" -#: common/models.py:3170 +#: common/models.py:3280 msgid "Date and time that the thread was last updated" msgstr "討論串最後更新的日期時間" @@ -2364,7 +2376,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:598 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 msgid "Items Received" msgstr "收到的物品" @@ -2378,11 +2390,11 @@ msgstr "已收到退貨訂單中的物品" #: common/serializers.py:125 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "指示變更此設定是否需要確認" #: common/serializers.py:139 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" +msgstr "變更此設定前需要確認。請確認變更。" #: common/serializers.py:172 msgid "Indicates if the setting is overridden by an environment variable" @@ -2392,1237 +2404,1305 @@ msgstr "表示此設定是否被環境變數覆蓋" msgid "Override" msgstr "覆蓋" -#: common/serializers.py:529 +#: common/serializers.py:610 msgid "Is Running" msgstr "正在運行" -#: common/serializers.py:535 +#: common/serializers.py:616 msgid "Pending Tasks" msgstr "等待完成的任務" -#: common/serializers.py:541 +#: common/serializers.py:622 msgid "Scheduled Tasks" msgstr "預定的任務" -#: common/serializers.py:547 +#: common/serializers.py:628 msgid "Failed Tasks" msgstr "失敗的任務" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Task ID" msgstr "任務ID" -#: common/serializers.py:562 +#: common/serializers.py:643 msgid "Unique task ID" msgstr "唯一任務ID" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock" msgstr "鎖定" -#: common/serializers.py:564 +#: common/serializers.py:645 msgid "Lock time" msgstr "鎖定時間" -#: common/serializers.py:566 +#: common/serializers.py:647 msgid "Task name" msgstr "任務名稱" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function" msgstr "功能" -#: common/serializers.py:568 +#: common/serializers.py:649 msgid "Function name" msgstr "功能名稱" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Arguments" msgstr "參數" -#: common/serializers.py:570 +#: common/serializers.py:651 msgid "Task arguments" msgstr "任務參數" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Keyword Arguments" msgstr "關鍵字參數" -#: common/serializers.py:573 +#: common/serializers.py:654 msgid "Task keyword arguments" msgstr "任務關鍵詞參數" -#: common/serializers.py:683 +#: common/serializers.py:764 msgid "Filename" msgstr "檔案名稱" -#: common/serializers.py:690 common/serializers.py:757 -#: common/serializers.py:832 importer/models.py:90 report/api.py:41 -#: report/models.py:293 report/serializers.py:52 +#: 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 msgid "Model Type" msgstr "模型類型" -#: common/serializers.py:718 +#: common/serializers.py:799 msgid "User does not have permission to create or edit attachments for this model" msgstr "用户無權為此模式創建或編輯附件" -#: common/serializers.py:813 +#: common/serializers.py:895 msgid "User does not have permission to create or edit parameters for this model" -msgstr "" +msgstr "使用者沒有權限建立或編輯此模型的參數" -#: common/serializers.py:883 common/serializers.py:986 +#: common/serializers.py:970 common/serializers.py:1073 msgid "Selection list is locked" msgstr "選擇列表已鎖定" -#: common/setting/system.py:96 +#: common/setting/system.py:97 msgid "No group" msgstr "無分組" -#: common/setting/system.py:169 +#: common/setting/system.py:170 msgid "Site URL is locked by configuration" msgstr "網站 URL 已配置為鎖定" -#: common/setting/system.py:186 +#: common/setting/system.py:187 msgid "Restart required" msgstr "需要重啓" -#: common/setting/system.py:187 +#: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" msgstr "設置已更改,需要服務器重啓" -#: common/setting/system.py:193 +#: common/setting/system.py:194 msgid "Pending migrations" msgstr "等待遷移" -#: common/setting/system.py:194 +#: common/setting/system.py:195 msgid "Number of pending database migrations" msgstr "待處理的數據庫遷移數" -#: common/setting/system.py:199 +#: common/setting/system.py:200 msgid "Active warning codes" msgstr "啟用中的警告碼" -#: common/setting/system.py:200 +#: common/setting/system.py:201 msgid "A dict of active warning codes" msgstr "啟用中警告碼的字典" -#: common/setting/system.py:206 +#: common/setting/system.py:207 msgid "Instance ID" msgstr "實例 ID" -#: common/setting/system.py:207 +#: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" msgstr "此 InvenTree 實例的唯一識別碼" -#: common/setting/system.py:212 +#: common/setting/system.py:213 msgid "Announce ID" msgstr "公告 ID" -#: common/setting/system.py:214 +#: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" msgstr "在伺服器狀態資訊中公告此伺服器的實例 ID(未驗證也可見)" -#: common/setting/system.py:220 +#: common/setting/system.py:221 msgid "Server Instance Name" msgstr "服務器實例名稱" -#: common/setting/system.py:222 +#: common/setting/system.py:223 msgid "String descriptor for the server instance" msgstr "服務器實例的字符串描述符" -#: common/setting/system.py:226 +#: common/setting/system.py:227 msgid "Use instance name" msgstr "使用實例名稱" -#: common/setting/system.py:227 +#: common/setting/system.py:228 msgid "Use the instance name in the title-bar" msgstr "在標題欄中使用實例名稱" -#: common/setting/system.py:232 +#: common/setting/system.py:233 msgid "Restrict showing `about`" msgstr "限制顯示 `關於` 信息" -#: common/setting/system.py:233 +#: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" msgstr "只向超級管理員顯示關於信息" -#: common/setting/system.py:238 company/models.py:146 company/models.py:147 +#: common/setting/system.py:239 +msgid "Show superuser banner" +msgstr "顯示超級使用者橫幅" + +#: common/setting/system.py:240 +msgid "Show a warning banner in the UI when logged in as superuser" +msgstr "以超級使用者身分登入時,在 UI 中顯示警告橫幅" + +#: common/setting/system.py:245 +msgid "Show admin banner" +msgstr "顯示管理員橫幅" + +#: common/setting/system.py:246 +msgid "Show a warning banner in the UI when logged in as admin" +msgstr "以管理員身分登入時,在 UI 中顯示警告橫幅" + +#: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" msgstr "公司名稱" -#: common/setting/system.py:239 +#: common/setting/system.py:252 msgid "Internal company name" msgstr "內部公司名稱" -#: common/setting/system.py:243 +#: common/setting/system.py:256 msgid "Base URL" msgstr "基本 URL" -#: common/setting/system.py:244 +#: common/setting/system.py:257 msgid "Base URL for server instance" msgstr "服務器實例的基準 URL" -#: common/setting/system.py:250 +#: common/setting/system.py:263 msgid "Default Currency" msgstr "默認貨幣單位" -#: common/setting/system.py:251 +#: common/setting/system.py:264 msgid "Select base currency for pricing calculations" msgstr "選擇價格計算的默認貨幣" -#: common/setting/system.py:257 +#: common/setting/system.py:270 msgid "Supported Currencies" msgstr "支持幣種" -#: common/setting/system.py:258 +#: common/setting/system.py:271 msgid "List of supported currency codes" msgstr "支持的貨幣代碼列表" -#: common/setting/system.py:264 +#: common/setting/system.py:277 msgid "Currency Update Interval" msgstr "貨幣更新間隔時間" -#: common/setting/system.py:265 +#: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "檢查更新的頻率(設置為零以禁用)" -#: common/setting/system.py:267 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:594 -#: common/setting/system.py:622 common/setting/system.py:721 -#: common/setting/system.py:1122 common/setting/system.py:1138 -#: common/setting/system.py:1155 +#: 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 msgid "days" msgstr "天" -#: common/setting/system.py:271 +#: common/setting/system.py:284 msgid "Currency Update Plugin" msgstr "幣種更新插件" -#: common/setting/system.py:272 +#: common/setting/system.py:285 msgid "Currency update plugin to use" msgstr "使用貨幣更新插件" -#: common/setting/system.py:277 -msgid "Download from URL" -msgstr "從URL下載" - -#: common/setting/system.py:278 -msgid "Allow download of remote images and files from external URL" -msgstr "允許從外部 URL 下載遠程圖片和文件" - -#: common/setting/system.py:283 -msgid "Download Size Limit" -msgstr "下載大小限制" - -#: common/setting/system.py:284 -msgid "Maximum allowable download size for remote image" -msgstr "遠程圖片的最大允許下載大小" - #: common/setting/system.py:290 -msgid "User-agent used to download from URL" -msgstr "用於從 URL 下載的 User-agent" - -#: common/setting/system.py:292 -msgid "Allow to override the user-agent used to download images and files from external URL (leave blank for the default)" -msgstr "允許覆蓋用於從外部 URL 下載圖片和文件的 user-agent(留空為默認值)" - -#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "嚴格的 URL 驗證" -#: common/setting/system.py:298 +#: common/setting/system.py:291 msgid "Require schema specification when validating URLs" msgstr "驗證 URL 時需要 schema 規範" -#: common/setting/system.py:303 +#: common/setting/system.py:296 msgid "Update Check Interval" msgstr "更新檢查間隔" -#: common/setting/system.py:304 +#: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" msgstr "檢查更新的頻率(設置為零以禁用)" -#: common/setting/system.py:310 +#: common/setting/system.py:303 msgid "Automatic Backup" msgstr "自動備份" -#: common/setting/system.py:311 +#: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" msgstr "啟動資料庫和媒體文件自動備份" -#: common/setting/system.py:316 +#: common/setting/system.py:309 msgid "Auto Backup Interval" msgstr "自動備份間隔" -#: common/setting/system.py:317 +#: common/setting/system.py:310 msgid "Specify number of days between automated backup events" msgstr "指定自動備份之間的間隔天數" -#: common/setting/system.py:323 +#: common/setting/system.py:316 msgid "Task Deletion Interval" msgstr "任務刪除間隔" -#: common/setting/system.py:325 +#: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" msgstr "後台任務結果將在指定天數後刪除" -#: common/setting/system.py:332 +#: common/setting/system.py:325 msgid "Error Log Deletion Interval" msgstr "錯誤日誌刪除間隔" -#: common/setting/system.py:333 +#: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" msgstr "錯誤日誌將在指定天數後被刪除" -#: common/setting/system.py:339 +#: common/setting/system.py:332 msgid "Notification Deletion Interval" msgstr "通知刪除間隔" -#: common/setting/system.py:341 +#: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" msgstr "用户通知將在指定天數後被刪除" -#: common/setting/system.py:348 +#: common/setting/system.py:341 msgid "Email Deletion Interval" msgstr "電子郵件刪除間隔" -#: common/setting/system.py:350 +#: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" msgstr "電子郵件訊息將在指定天數後刪除" -#: common/setting/system.py:357 +#: common/setting/system.py:350 msgid "Protect Email Log" msgstr "保護電子郵件日誌" -#: common/setting/system.py:358 +#: common/setting/system.py:351 msgid "Prevent deletion of email log entries" msgstr "防止刪除電子郵件日誌紀錄" -#: common/setting/system.py:363 +#: common/setting/system.py:356 msgid "Barcode Support" msgstr "條形碼支持" -#: common/setting/system.py:364 +#: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" msgstr "在網頁界面啓用條形碼掃描器支持" -#: common/setting/system.py:369 +#: common/setting/system.py:362 msgid "Store Barcode Results" msgstr "存儲條碼結果" -#: common/setting/system.py:370 +#: common/setting/system.py:363 msgid "Store barcode scan results in the database" msgstr "存儲條碼掃描結果" -#: common/setting/system.py:375 +#: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" msgstr "條碼掃描最大計數" -#: common/setting/system.py:376 +#: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" msgstr "存儲條碼掃描結果的最大數量" -#: common/setting/system.py:381 +#: common/setting/system.py:374 msgid "Barcode Input Delay" msgstr "條形碼掃描延遲設置" -#: common/setting/system.py:382 +#: common/setting/system.py:375 msgid "Barcode input processing delay time" msgstr "條形碼輸入處理延遲時間" -#: common/setting/system.py:388 +#: common/setting/system.py:381 msgid "Barcode Webcam Support" msgstr "條碼攝像頭支持" -#: common/setting/system.py:389 +#: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" msgstr "允許通過網絡攝像頭掃描條形碼" -#: common/setting/system.py:394 +#: common/setting/system.py:387 msgid "Barcode Show Data" msgstr "條形碼顯示數據" -#: common/setting/system.py:395 +#: common/setting/system.py:388 msgid "Display barcode data in browser as text" msgstr "在瀏覽器中將條形碼數據顯示為文本" -#: common/setting/system.py:400 +#: common/setting/system.py:393 msgid "Barcode Generation Plugin" msgstr "條形碼生成插件" -#: common/setting/system.py:401 +#: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" msgstr "用於內部條形碼數據生成的插件" -#: common/setting/system.py:406 +#: common/setting/system.py:399 msgid "Part Revisions" msgstr "零件修訂" -#: common/setting/system.py:407 +#: common/setting/system.py:400 msgid "Enable revision field for Part" msgstr "啓用零件修訂字段" -#: common/setting/system.py:412 +#: common/setting/system.py:405 msgid "Assembly Revision Only" msgstr "僅限裝配修訂版本" -#: common/setting/system.py:413 +#: common/setting/system.py:406 msgid "Only allow revisions for assembly parts" msgstr "僅允許對裝配零件進行修訂" -#: common/setting/system.py:418 +#: common/setting/system.py:411 msgid "Allow Deletion from Assembly" msgstr "允許從裝配中刪除" -#: common/setting/system.py:419 +#: common/setting/system.py:412 msgid "Allow deletion of parts which are used in an assembly" msgstr "允許刪除已在裝配中使用的零件" -#: common/setting/system.py:424 +#: common/setting/system.py:417 msgid "IPN Regex" msgstr "IPN 內部零件號" -#: common/setting/system.py:425 +#: common/setting/system.py:418 msgid "Regular expression pattern for matching Part IPN" msgstr "匹配零件 IPN(內部零件號)的正則表達式模式" -#: common/setting/system.py:428 +#: common/setting/system.py:421 msgid "Allow Duplicate IPN" msgstr "允許重複的 IPN(內部零件號)" -#: common/setting/system.py:429 +#: common/setting/system.py:422 msgid "Allow multiple parts to share the same IPN" msgstr "允許多個零件共享相同的 IPN(內部零件號)" -#: common/setting/system.py:434 +#: common/setting/system.py:427 msgid "Allow Editing IPN" msgstr "允許編輯 IPN(內部零件號)" -#: common/setting/system.py:435 +#: common/setting/system.py:428 msgid "Allow changing the IPN value while editing a part" msgstr "允許編輯零件時更改內部零件號" -#: common/setting/system.py:440 +#: common/setting/system.py:433 msgid "Copy Part BOM Data" msgstr "複製零件物料清單數據" -#: common/setting/system.py:441 +#: common/setting/system.py:434 msgid "Copy BOM data by default when duplicating a part" msgstr "複製零件時默認複製物料清單數據" -#: common/setting/system.py:446 +#: common/setting/system.py:439 msgid "Copy Part Parameter Data" msgstr "複製零件參數數據" -#: common/setting/system.py:447 +#: common/setting/system.py:440 msgid "Copy parameter data by default when duplicating a part" msgstr "複製零件時默認複製參數數據" -#: common/setting/system.py:452 +#: common/setting/system.py:445 msgid "Copy Part Test Data" msgstr "複製零件測試數據" -#: common/setting/system.py:453 +#: common/setting/system.py:446 msgid "Copy test data by default when duplicating a part" msgstr "複製零件時默認複製測試數據" -#: common/setting/system.py:458 +#: common/setting/system.py:451 msgid "Copy Category Parameter Templates" msgstr "複製類別參數模板" -#: common/setting/system.py:459 +#: common/setting/system.py:452 msgid "Copy category parameter templates when creating a part" msgstr "創建零件時複製類別參數模板" -#: common/setting/system.py:465 +#: common/setting/system.py:458 msgid "Parts are templates by default" msgstr "零件默認為模板" -#: common/setting/system.py:471 +#: common/setting/system.py:464 msgid "Parts can be assembled from other components by default" msgstr "默認情況下,元件可由其他零件組裝而成" -#: common/setting/system.py:476 part/models.py:1259 part/serializers.py:1694 -#: part/serializers.py:1701 +#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 +#: part/serializers.py:1748 msgid "Component" msgstr "組件" -#: common/setting/system.py:477 +#: common/setting/system.py:470 msgid "Parts can be used as sub-components by default" msgstr "默認情況下,零件可用作子部件" -#: common/setting/system.py:482 part/models.py:1277 +#: common/setting/system.py:475 part/models.py:1281 msgid "Purchaseable" msgstr "可購買" -#: common/setting/system.py:483 +#: common/setting/system.py:476 msgid "Parts are purchaseable by default" msgstr "默認情況下可購買零件" -#: common/setting/system.py:488 part/models.py:1283 stock/api.py:643 +#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 msgid "Salable" msgstr "可銷售" -#: common/setting/system.py:489 +#: common/setting/system.py:482 msgid "Parts are salable by default" msgstr "零件默認為可銷售" -#: common/setting/system.py:495 +#: common/setting/system.py:488 msgid "Parts are trackable by default" msgstr "默認情況下可跟蹤零件" -#: common/setting/system.py:500 part/models.py:1299 +#: common/setting/system.py:493 part/models.py:1303 msgid "Virtual" msgstr "虛擬的" -#: common/setting/system.py:501 +#: common/setting/system.py:494 msgid "Parts are virtual by default" msgstr "默認情況下,零件是虛擬的" -#: common/setting/system.py:506 +#: common/setting/system.py:499 msgid "Show related parts" msgstr "顯示相關零件" -#: common/setting/system.py:507 +#: common/setting/system.py:500 msgid "Display related parts for a part" msgstr "顯示零件的相關零件" -#: common/setting/system.py:512 +#: common/setting/system.py:505 msgid "Initial Stock Data" msgstr "初始庫存數據" -#: common/setting/system.py:513 +#: common/setting/system.py:506 msgid "Allow creation of initial stock when adding a new part" msgstr "允許在添加新零件時創建初始庫存" -#: common/setting/system.py:518 +#: common/setting/system.py:511 msgid "Initial Supplier Data" msgstr "初始供應商數據" -#: common/setting/system.py:520 +#: common/setting/system.py:513 msgid "Allow creation of initial supplier data when adding a new part" msgstr "允許在添加新零件時創建初始供應商數據" -#: common/setting/system.py:526 +#: common/setting/system.py:519 msgid "Part Name Display Format" msgstr "零件名稱顯示格式" -#: common/setting/system.py:527 +#: common/setting/system.py:520 msgid "Format to display the part name" msgstr "顯示零件名稱的格式" -#: common/setting/system.py:533 +#: common/setting/system.py:526 msgid "Part Category Default Icon" msgstr "零件類別默認圖標" -#: common/setting/system.py:534 +#: common/setting/system.py:527 msgid "Part category default icon (empty means no icon)" msgstr "零件類別默認圖標 (空表示沒有圖標)" -#: common/setting/system.py:539 +#: common/setting/system.py:532 msgid "Minimum Pricing Decimal Places" msgstr "最小定價小數位數" -#: common/setting/system.py:541 +#: common/setting/system.py:534 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "呈現定價數據時顯示的最小小數位數" -#: common/setting/system.py:552 +#: common/setting/system.py:545 msgid "Maximum Pricing Decimal Places" msgstr "最大定價小數位數" -#: common/setting/system.py:554 +#: common/setting/system.py:547 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "呈現定價數據時顯示的最大小數位數" -#: common/setting/system.py:565 +#: common/setting/system.py:558 msgid "Use Supplier Pricing" msgstr "使用供應商定價" -#: common/setting/system.py:567 +#: common/setting/system.py:560 msgid "Include supplier price breaks in overall pricing calculations" msgstr "將供應商的價批發價納入總體定價計算中" -#: common/setting/system.py:573 +#: common/setting/system.py:566 msgid "Purchase History Override" msgstr "購買歷史記錄覆蓋" -#: common/setting/system.py:575 +#: common/setting/system.py:568 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "歷史採購訂單定價優先於供應商批發價" -#: common/setting/system.py:581 +#: common/setting/system.py:574 msgid "Use Stock Item Pricing" msgstr "使用庫存項定價" -#: common/setting/system.py:583 +#: common/setting/system.py:576 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "使用手動輸入的庫存數據進行定價計算" -#: common/setting/system.py:589 +#: common/setting/system.py:582 msgid "Stock Item Pricing Age" msgstr "庫存項目定價時間" -#: common/setting/system.py:591 +#: common/setting/system.py:584 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "從定價計算中排除超過此天數的庫存項目" -#: common/setting/system.py:598 +#: common/setting/system.py:591 msgid "Use Variant Pricing" msgstr "使用變體定價" -#: common/setting/system.py:599 +#: common/setting/system.py:592 msgid "Include variant pricing in overall pricing calculations" msgstr "在整體定價計算中包括變體定價" -#: common/setting/system.py:604 +#: common/setting/system.py:597 msgid "Active Variants Only" msgstr "僅限活躍變體" -#: common/setting/system.py:606 +#: common/setting/system.py:599 msgid "Only use active variant parts for calculating variant pricing" msgstr "僅使用活躍變體零件計算變體價格" -#: common/setting/system.py:612 +#: common/setting/system.py:605 msgid "Auto Update Pricing" msgstr "自動更新定價" -#: common/setting/system.py:614 +#: common/setting/system.py:607 msgid "Automatically update part pricing when internal data changes" msgstr "當內部資料變更時自動更新零件定價" -#: common/setting/system.py:620 +#: common/setting/system.py:613 msgid "Pricing Rebuild Interval" msgstr "價格重建間隔" -#: common/setting/system.py:621 +#: common/setting/system.py:614 msgid "Number of days before part pricing is automatically updated" msgstr "零件價格自動更新前的天數" -#: common/setting/system.py:627 +#: common/setting/system.py:620 msgid "Internal Prices" msgstr "內部價格" -#: common/setting/system.py:628 +#: common/setting/system.py:621 msgid "Enable internal prices for parts" msgstr "啓用內部零件價格" -#: common/setting/system.py:633 +#: common/setting/system.py:626 msgid "Internal Price Override" msgstr "覆蓋內部價格" -#: common/setting/system.py:635 +#: common/setting/system.py:628 msgid "If available, internal prices override price range calculations" msgstr "如果有內部價格,內部價格將覆蓋價格範圍計算" -#: common/setting/system.py:641 +#: common/setting/system.py:634 +msgid "Allow BOM Zero Quantity" +msgstr "允許 BOM 零數量" + +#: common/setting/system.py:636 +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 msgid "Enable label printing" msgstr "啓用標籤打印功能" -#: common/setting/system.py:642 +#: common/setting/system.py:643 msgid "Enable label printing from the web interface" msgstr "啓用從網絡界面打印標籤" -#: common/setting/system.py:647 +#: common/setting/system.py:648 msgid "Label Image DPI" msgstr "標籤圖片 DPI" -#: common/setting/system.py:649 +#: common/setting/system.py:650 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "生成圖像文件以供標籤打印插件使用時的 DPI 分辨率" -#: common/setting/system.py:655 +#: common/setting/system.py:656 msgid "Enable Reports" msgstr "啓用報告" -#: common/setting/system.py:656 +#: common/setting/system.py:657 msgid "Enable generation of reports" msgstr "啓用報告生成" -#: common/setting/system.py:661 +#: common/setting/system.py:662 msgid "Debug Mode" msgstr "調試模式" -#: common/setting/system.py:662 +#: common/setting/system.py:663 msgid "Generate reports in debug mode (HTML output)" msgstr "以調試模式生成報告(HTML 輸出)" -#: common/setting/system.py:667 +#: common/setting/system.py:668 msgid "Log Report Errors" msgstr "日誌錯誤報告" -#: common/setting/system.py:668 +#: common/setting/system.py:669 msgid "Log errors which occur when generating reports" msgstr "記錄生成報告時出現的錯誤" -#: common/setting/system.py:673 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:381 +#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 +#: report/models.py:386 msgid "Page Size" msgstr "頁面大小" -#: common/setting/system.py:674 +#: common/setting/system.py:675 msgid "Default page size for PDF reports" msgstr "PDF 報告默認頁面大小" -#: common/setting/system.py:679 +#: common/setting/system.py:680 msgid "Enforce Parameter Units" msgstr "強制參數單位" -#: common/setting/system.py:681 +#: common/setting/system.py:682 msgid "If units are provided, parameter values must match the specified units" msgstr "如果提供了單位,參數值必須與指定的單位匹配" -#: common/setting/system.py:687 +#: common/setting/system.py:688 msgid "Globally Unique Serials" msgstr "全局唯一序列號" -#: common/setting/system.py:688 +#: common/setting/system.py:689 msgid "Serial numbers for stock items must be globally unique" msgstr "庫存項的序列號必須全局唯一" -#: common/setting/system.py:693 +#: common/setting/system.py:694 msgid "Delete Depleted Stock" msgstr "刪除已耗盡的庫存" -#: common/setting/system.py:694 +#: common/setting/system.py:695 msgid "Determines default behavior when a stock item is depleted" msgstr "設置庫存耗盡時的默認行為" -#: common/setting/system.py:699 +#: common/setting/system.py:700 +msgid "Allow Edit Serial Number" +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" +msgstr "" + +#: common/setting/system.py:707 +msgid "Allow deletion of stock items which have a serial number" +msgstr "" + +#: common/setting/system.py:712 msgid "Batch Code Template" msgstr "批號模板" -#: common/setting/system.py:700 +#: common/setting/system.py:713 msgid "Template for generating default batch codes for stock items" msgstr "為庫存項生成默認批號的模板" -#: common/setting/system.py:704 +#: common/setting/system.py:717 msgid "Stock Expiry" msgstr "庫存過期" -#: common/setting/system.py:705 +#: common/setting/system.py:718 msgid "Enable stock expiry functionality" msgstr "啓用庫存過期功能" -#: common/setting/system.py:710 +#: common/setting/system.py:723 msgid "Sell Expired Stock" msgstr "銷售過期庫存" -#: common/setting/system.py:711 +#: common/setting/system.py:724 msgid "Allow sale of expired stock" msgstr "允許銷售過期庫存" -#: common/setting/system.py:716 +#: common/setting/system.py:729 msgid "Stock Stale Time" msgstr "庫存過期時間" -#: common/setting/system.py:718 +#: common/setting/system.py:731 msgid "Number of days stock items are considered stale before expiring" msgstr "庫存項在到期前被視為過期的天數" -#: common/setting/system.py:725 +#: common/setting/system.py:738 msgid "Build Expired Stock" msgstr "生產過期庫存" -#: common/setting/system.py:726 +#: common/setting/system.py:739 msgid "Allow building with expired stock" msgstr "允許用過期的庫存生產" -#: common/setting/system.py:731 +#: common/setting/system.py:744 msgid "Stock Ownership Control" msgstr "庫存所有權控制" -#: common/setting/system.py:732 +#: common/setting/system.py:745 msgid "Enable ownership control over stock locations and items" msgstr "啓用庫存地點和項目的所有權控制" -#: common/setting/system.py:737 +#: common/setting/system.py:750 msgid "Stock Location Default Icon" msgstr "庫存地點默認圖標" -#: common/setting/system.py:738 +#: common/setting/system.py:751 msgid "Stock location default icon (empty means no icon)" msgstr "庫存地點默認圖標 (空表示沒有圖標)" -#: common/setting/system.py:743 +#: common/setting/system.py:756 msgid "Show Installed Stock Items" msgstr "顯示已安裝的庫存項" -#: common/setting/system.py:744 +#: common/setting/system.py:757 msgid "Display installed stock items in stock tables" msgstr "在庫存表中顯示已安裝的庫存項" -#: common/setting/system.py:749 +#: common/setting/system.py:762 msgid "Check BOM when installing items" msgstr "在安裝項目時檢查物料清單" -#: common/setting/system.py:751 +#: common/setting/system.py:764 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "已安裝的庫存項目必須存在於上級零件的物料清單中" -#: common/setting/system.py:757 +#: common/setting/system.py:770 msgid "Allow Out of Stock Transfer" msgstr "允許超出庫存轉移" -#: common/setting/system.py:759 +#: 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:765 +#: common/setting/system.py:778 msgid "Build Order Reference Pattern" msgstr "生產訂單參考模式" -#: common/setting/system.py:766 +#: common/setting/system.py:779 msgid "Required pattern for generating Build Order reference field" msgstr "生成生產訂單參考字段所需的模式" -#: common/setting/system.py:771 common/setting/system.py:831 -#: common/setting/system.py:851 common/setting/system.py:895 +#: 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:772 common/setting/system.py:832 -#: common/setting/system.py:852 common/setting/system.py:896 +#: 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:777 +#: common/setting/system.py:790 msgid "Require Active Part" msgstr "需要活動零件" -#: common/setting/system.py:778 +#: common/setting/system.py:791 msgid "Prevent build order creation for inactive parts" msgstr "防止為非活動零件創建生產訂單" -#: common/setting/system.py:783 +#: common/setting/system.py:796 msgid "Require Locked Part" msgstr "需要鎖定零件" -#: common/setting/system.py:784 +#: common/setting/system.py:797 msgid "Prevent build order creation for unlocked parts" msgstr "防止為未鎖定的零件創建生產訂單" -#: common/setting/system.py:789 +#: common/setting/system.py:802 msgid "Require Valid BOM" msgstr "需要有效的物料清單" -#: common/setting/system.py:790 +#: common/setting/system.py:803 msgid "Prevent build order creation unless BOM has been validated" msgstr "除非物料清單已驗證,否則禁止創建生產訂單" -#: common/setting/system.py:795 +#: common/setting/system.py:808 msgid "Require Closed Child Orders" msgstr "需要關閉子訂單" -#: common/setting/system.py:797 +#: common/setting/system.py:810 msgid "Prevent build order completion until all child orders are closed" msgstr "在所有子訂單關閉之前,阻止生產訂單的完成" -#: common/setting/system.py:803 +#: common/setting/system.py:816 msgid "External Build Orders" msgstr "外部生產工單" -#: common/setting/system.py:804 +#: common/setting/system.py:817 msgid "Enable external build order functionality" msgstr "啟用外部生產工單功能" -#: common/setting/system.py:809 +#: common/setting/system.py:822 +msgid "Require External Build Orders" +msgstr "" + +#: common/setting/system.py:824 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "" + +#: common/setting/system.py:830 msgid "Block Until Tests Pass" msgstr "阻止直到測試通過" -#: common/setting/system.py:811 +#: common/setting/system.py:832 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "在所有必要的測試通過之前,阻止產出完成" -#: common/setting/system.py:817 +#: common/setting/system.py:838 msgid "Enable Return Orders" msgstr "啓用訂單退貨" -#: common/setting/system.py:818 +#: common/setting/system.py:839 msgid "Enable return order functionality in the user interface" msgstr "在用户界面中啓用訂單退貨功能" -#: common/setting/system.py:823 +#: common/setting/system.py:844 msgid "Return Order Reference Pattern" msgstr "退貨訂單參考模式" -#: common/setting/system.py:825 +#: common/setting/system.py:846 msgid "Required pattern for generating Return Order reference field" msgstr "生成退貨訂單參考字段所需的模式" -#: common/setting/system.py:837 +#: common/setting/system.py:858 msgid "Edit Completed Return Orders" msgstr "編輯已完成的退貨訂單" -#: common/setting/system.py:839 +#: common/setting/system.py:860 msgid "Allow editing of return orders after they have been completed" msgstr "允許編輯已完成的退貨訂單" -#: common/setting/system.py:845 +#: common/setting/system.py:866 msgid "Sales Order Reference Pattern" msgstr "銷售訂單參考模式" -#: common/setting/system.py:846 +#: common/setting/system.py:867 msgid "Required pattern for generating Sales Order reference field" msgstr "生成銷售訂單參考字段所需參照模式" -#: common/setting/system.py:857 +#: common/setting/system.py:878 msgid "Sales Order Default Shipment" msgstr "銷售訂單默認配送方式" -#: common/setting/system.py:858 +#: common/setting/system.py:879 msgid "Enable creation of default shipment with sales orders" msgstr "啓用創建銷售訂單的默認配送功能" -#: common/setting/system.py:863 +#: common/setting/system.py:884 msgid "Edit Completed Sales Orders" msgstr "編輯已完成的銷售訂單" -#: common/setting/system.py:865 +#: common/setting/system.py:886 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "允許在訂單配送或完成後編輯銷售訂單" -#: common/setting/system.py:871 +#: common/setting/system.py:892 msgid "Shipment Requires Checking" -msgstr "" +msgstr "發貨需要檢查" -#: common/setting/system.py:873 +#: common/setting/system.py:894 msgid "Prevent completion of shipments until items have been checked" -msgstr "" +msgstr "在項目被檢查前,防止完成發貨" -#: common/setting/system.py:879 +#: common/setting/system.py:900 msgid "Mark Shipped Orders as Complete" msgstr "標記該訂單為已完成?" -#: common/setting/system.py:881 +#: common/setting/system.py:902 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "標記為已發貨的銷售訂單將自動完成,繞過“已發貨”狀態" -#: common/setting/system.py:887 +#: common/setting/system.py:908 +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:889 +#: common/setting/system.py:918 msgid "Required pattern for generating Purchase Order reference field" msgstr "生成採購訂單參考字段所需的模式" -#: common/setting/system.py:901 +#: common/setting/system.py:930 msgid "Edit Completed Purchase Orders" msgstr "編輯已完成的採購訂單" -#: common/setting/system.py:903 +#: common/setting/system.py:932 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "允許在採購訂單已配送或完成後編輯訂單" -#: common/setting/system.py:909 +#: common/setting/system.py:938 msgid "Convert Currency" msgstr "轉換幣別" -#: common/setting/system.py:910 +#: common/setting/system.py:939 msgid "Convert item value to base currency when receiving stock" msgstr "收貨時將項目價值換算為基準幣別" -#: common/setting/system.py:915 +#: common/setting/system.py:944 msgid "Auto Complete Purchase Orders" msgstr "自動完成採購訂單" -#: common/setting/system.py:917 +#: common/setting/system.py:946 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "當收到所有行項目時,自動將採購訂單標記為完成" -#: common/setting/system.py:924 +#: common/setting/system.py:953 msgid "Enable password forgot" msgstr "忘記啓用密碼" -#: common/setting/system.py:925 +#: common/setting/system.py:954 msgid "Enable password forgot function on the login pages" msgstr "在登錄頁面上啓用忘記密碼功能" -#: common/setting/system.py:930 +#: common/setting/system.py:959 msgid "Enable registration" msgstr "啓用註冊" -#: common/setting/system.py:931 +#: common/setting/system.py:960 msgid "Enable self-registration for users on the login pages" msgstr "在登錄頁面為用户啓用自行註冊功能" -#: common/setting/system.py:936 +#: common/setting/system.py:965 msgid "Enable SSO" msgstr "啓用單點登錄" -#: common/setting/system.py:937 +#: common/setting/system.py:966 msgid "Enable SSO on the login pages" msgstr "在登錄界面啓用單點登錄" -#: common/setting/system.py:942 +#: common/setting/system.py:971 msgid "Enable SSO registration" msgstr "啓用單點登錄註冊" -#: common/setting/system.py:944 +#: common/setting/system.py:973 msgid "Enable self-registration via SSO for users on the login pages" msgstr "允許登錄頁面上的用户通過 SSO 進行自我註冊" -#: common/setting/system.py:950 +#: common/setting/system.py:979 msgid "Enable SSO group sync" msgstr "啓用單點登錄羣組同步" -#: common/setting/system.py:952 +#: common/setting/system.py:981 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "啓用庫存管理系統組和由身份提供者提供的組的同步功能" -#: common/setting/system.py:958 +#: common/setting/system.py:987 msgid "SSO group key" msgstr "單點登錄系統組密鑰" -#: common/setting/system.py:959 +#: common/setting/system.py:988 msgid "The name of the groups claim attribute provided by the IdP" msgstr "由身份提供者提供的組聲明屬性名稱" -#: common/setting/system.py:964 +#: common/setting/system.py:993 msgid "SSO group map" msgstr "單點登錄系統組地圖" -#: common/setting/system.py:966 +#: 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:972 +#: common/setting/system.py:1001 msgid "Remove groups outside of SSO" msgstr "移除單點登錄系統以外的羣組" -#: common/setting/system.py:974 +#: 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 "如果分配給用户的組不是身份提供者的後端,是否應該刪除它們。禁用此設置可能會造成安全問題" -#: common/setting/system.py:980 +#: common/setting/system.py:1009 msgid "Email required" msgstr "需要郵箱地址" -#: common/setting/system.py:981 +#: common/setting/system.py:1010 msgid "Require user to supply mail on signup" msgstr "要求用户在註冊時提供郵件" -#: common/setting/system.py:986 +#: common/setting/system.py:1015 msgid "Auto-fill SSO users" msgstr "自動填充單點登錄系統用户" -#: common/setting/system.py:987 +#: common/setting/system.py:1016 msgid "Automatically fill out user-details from SSO account-data" msgstr "自動使用單點登錄系統賬户的數據填寫用户詳細信息" -#: common/setting/system.py:992 +#: common/setting/system.py:1021 msgid "Mail twice" msgstr "發兩次郵件" -#: common/setting/system.py:993 +#: common/setting/system.py:1022 msgid "On signup ask users twice for their mail" msgstr "註冊時詢問用户他們的電子郵件兩次" -#: common/setting/system.py:998 +#: common/setting/system.py:1027 msgid "Password twice" msgstr "兩次輸入密碼" -#: common/setting/system.py:999 +#: common/setting/system.py:1028 msgid "On signup ask users twice for their password" msgstr "當註冊時請用户輸入密碼兩次" -#: common/setting/system.py:1004 +#: common/setting/system.py:1033 msgid "Allowed domains" msgstr "域名白名單" -#: common/setting/system.py:1006 +#: common/setting/system.py:1035 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "限制註冊到某些域名 (逗號分隔,以 @ 開頭)" -#: common/setting/system.py:1012 +#: common/setting/system.py:1041 msgid "Group on signup" msgstr "註冊羣組" -#: common/setting/system.py:1014 +#: 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." msgstr "註冊時分配給新用户的組。 如果啓用了單點登錄系統羣組同步,此羣組僅在無法從 IdP 分配任何羣組的情況下才被設置。" -#: common/setting/system.py:1020 +#: common/setting/system.py:1049 msgid "Enforce MFA" msgstr "強制啓用多因素安全認證" -#: common/setting/system.py:1021 +#: common/setting/system.py:1050 msgid "Users must use multifactor security." msgstr "用户必須使用多因素安全認證。" -#: common/setting/system.py:1026 +#: 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 "" +msgstr "啟用此設定將要求所有使用者設定多因素驗證。所有工作階段將立即中斷連線。" -#: common/setting/system.py:1031 +#: common/setting/system.py:1060 msgid "Check plugins on startup" msgstr "啓動時檢查插件" -#: common/setting/system.py:1033 +#: common/setting/system.py:1062 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "啓動時檢查全部插件是否已安裝 - 在容器環境中啓用" -#: common/setting/system.py:1040 +#: common/setting/system.py:1069 msgid "Check for plugin updates" msgstr "檢查插件更新" -#: common/setting/system.py:1041 +#: common/setting/system.py:1070 msgid "Enable periodic checks for updates to installed plugins" msgstr "啓用定期檢查已安裝插件的更新" -#: common/setting/system.py:1047 +#: common/setting/system.py:1076 msgid "Enable URL integration" msgstr "啓用統一資源定位符集成" -#: common/setting/system.py:1048 +#: common/setting/system.py:1077 msgid "Enable plugins to add URL routes" msgstr "啓用插件以添加統一資源定位符路由" -#: common/setting/system.py:1054 +#: common/setting/system.py:1083 msgid "Enable navigation integration" msgstr "啓用導航集成" -#: common/setting/system.py:1055 +#: common/setting/system.py:1084 msgid "Enable plugins to integrate into navigation" msgstr "啓用插件以集成到導航中" -#: common/setting/system.py:1061 +#: common/setting/system.py:1090 msgid "Enable app integration" msgstr "啓用應用集成" -#: common/setting/system.py:1062 +#: common/setting/system.py:1091 msgid "Enable plugins to add apps" msgstr "啓用插件添加應用" -#: common/setting/system.py:1068 +#: common/setting/system.py:1097 msgid "Enable schedule integration" msgstr "啓用調度集成" -#: common/setting/system.py:1069 +#: common/setting/system.py:1098 msgid "Enable plugins to run scheduled tasks" msgstr "啓用插件來運行預定任務" -#: common/setting/system.py:1075 +#: common/setting/system.py:1104 msgid "Enable event integration" msgstr "啓用事件集成" -#: common/setting/system.py:1076 +#: common/setting/system.py:1105 msgid "Enable plugins to respond to internal events" msgstr "啓用插件響應內部事件" -#: common/setting/system.py:1082 +#: common/setting/system.py:1111 msgid "Enable interface integration" msgstr "啓用界面集成" -#: common/setting/system.py:1083 +#: common/setting/system.py:1112 msgid "Enable plugins to integrate into the user interface" msgstr "啓用插件集成到用户界面" -#: common/setting/system.py:1089 +#: common/setting/system.py:1118 msgid "Enable mail integration" msgstr "啟用郵件整合" -#: common/setting/system.py:1090 +#: common/setting/system.py:1119 msgid "Enable plugins to process outgoing/incoming mails" msgstr "允許模組處理寄出/接收郵件" -#: common/setting/system.py:1096 +#: common/setting/system.py:1125 msgid "Enable project codes" msgstr "啟用專案代碼" -#: common/setting/system.py:1097 +#: common/setting/system.py:1126 msgid "Enable project codes for tracking projects" msgstr "啟用專案代碼以追蹤專案" -#: common/setting/system.py:1102 +#: common/setting/system.py:1131 msgid "Enable Stocktake" -msgstr "" +msgstr "啟用盤點" -#: common/setting/system.py:1104 +#: common/setting/system.py:1133 msgid "Enable functionality for recording historical stock levels and value" msgstr "啟用記錄庫存數量及價值歷史的功能" -#: common/setting/system.py:1110 +#: common/setting/system.py:1139 msgid "Exclude External Locations" msgstr "排除外部地點" -#: common/setting/system.py:1112 +#: common/setting/system.py:1141 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "從盤點計算中排除外部位置的庫存項目" -#: common/setting/system.py:1118 +#: common/setting/system.py:1147 msgid "Automatic Stocktake Period" msgstr "自動盤點週期" -#: common/setting/system.py:1119 +#: common/setting/system.py:1148 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "自動記錄盤點的天數間隔" -#: common/setting/system.py:1125 +#: common/setting/system.py:1154 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "刪除舊的盤點項目" -#: common/setting/system.py:1127 +#: common/setting/system.py:1156 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "刪除超過指定天數的盤點項目" -#: common/setting/system.py:1133 +#: common/setting/system.py:1162 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "盤點刪除間隔" -#: common/setting/system.py:1135 +#: common/setting/system.py:1164 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "盤點項目將在指定天數後刪除" -#: common/setting/system.py:1142 +#: common/setting/system.py:1171 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "刪除舊庫存的追蹤紀錄" -#: common/setting/system.py:1144 +#: common/setting/system.py:1173 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +msgstr "刪除超過指定天數的庫存追蹤項目" -#: common/setting/system.py:1150 +#: common/setting/system.py:1179 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "庫存追蹤刪除間隔" -#: common/setting/system.py:1152 +#: common/setting/system.py:1181 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgstr "庫存追蹤項目將在指定天數後刪除" -#: common/setting/system.py:1159 +#: common/setting/system.py:1188 msgid "Display Users full names" msgstr "顯示用户全名" -#: common/setting/system.py:1160 +#: common/setting/system.py:1189 msgid "Display Users full names instead of usernames" msgstr "顯示用户全名而不是用户名" -#: common/setting/system.py:1165 +#: common/setting/system.py:1194 msgid "Display User Profiles" msgstr "顯示使用者個人檔案" -#: common/setting/system.py:1166 +#: common/setting/system.py:1195 msgid "Display Users Profiles on their profile page" msgstr "在個人頁面顯示使用者檔案資訊" -#: common/setting/system.py:1171 +#: 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: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" +msgstr "" + +#: common/setting/system.py:1210 +msgid "Saturday" +msgstr "" + +#: common/setting/system.py:1214 msgid "Enable Test Station Data" msgstr "啓用測試站數據" -#: common/setting/system.py:1172 +#: common/setting/system.py:1215 msgid "Enable test station data collection for test results" msgstr "啓用測試站數據收集以獲取測試結果" -#: common/setting/system.py:1177 +#: common/setting/system.py:1220 msgid "Enable Machine Ping" -msgstr "" +msgstr "啟用設備 Ping" -#: common/setting/system.py:1179 +#: common/setting/system.py:1222 msgid "Enable periodic ping task of registered machines to check their status" -msgstr "" +msgstr "啟用對已註冊機器的定期 ping 任務以檢查其狀態" #: common/setting/user.py:23 msgid "Inline label display" @@ -3650,11 +3730,11 @@ msgstr "在瀏覽器中顯示PDF報告,而不是作為文件下載" #: common/setting/user.py:45 msgid "Barcode Scanner in Form Fields" -msgstr "" +msgstr "表單欄位中的條碼掃描器" #: common/setting/user.py:46 msgid "Allow barcode scanner input in form fields" -msgstr "" +msgstr "允許在表單欄位中使用條碼掃描器輸入" #: common/setting/user.py:51 msgid "Search Parts" @@ -3905,24 +3985,40 @@ msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled 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" +msgstr "" + +#: common/setting/user.py:261 msgid "Receive error reports" msgstr "接收錯誤報告" -#: common/setting/user.py:256 +#: common/setting/user.py:262 msgid "Receive notifications for system errors" msgstr "接收系統錯誤通知" -#: common/setting/user.py:261 +#: common/setting/user.py:267 msgid "Last used printing machines" msgstr "上次使用的打印設備" -#: common/setting/user.py:262 +#: common/setting/user.py:268 msgid "Save the last used printing machines for a user" msgstr "為用户保存上次使用的打印設備" +#: common/setting/user.py:272 +msgid "Display Items at Final Level" +msgstr "" + +#: common/setting/user.py:274 +msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" +msgstr "" + #: common/validators.py:38 msgid "All models" -msgstr "" +msgstr "所有模型" #: common/validators.py:63 msgid "No attachment model type provided" @@ -3965,364 +4061,368 @@ msgstr "零件已激活" msgid "Manufacturer is Active" msgstr "製造商處於活動狀態" -#: company/api.py:250 +#: company/api.py:252 msgid "Supplier Part is Active" msgstr "供應商零件處於激活狀態" -#: company/api.py:252 +#: company/api.py:254 msgid "Primary Supplier Part" -msgstr "" +msgstr "主要供應商零件" -#: company/api.py:256 +#: company/api.py:258 msgid "Internal Part is Active" msgstr "內部零件已激活" -#: company/api.py:261 +#: company/api.py:263 msgid "Supplier is Active" msgstr "供應商已激活" -#: company/api.py:273 company/models.py:530 company/serializers.py:455 -#: part/serializers.py:478 +#: company/api.py:275 company/models.py:535 company/serializers.py:446 +#: part/serializers.py:489 msgid "Manufacturer" msgstr "製造商" -#: company/api.py:280 company/models.py:123 company/models.py:399 -#: stock/api.py:900 +#: company/api.py:282 company/models.py:124 company/models.py:404 +#: stock/api.py:899 msgid "Company" msgstr "公司" -#: company/api.py:290 +#: company/api.py:292 msgid "Has Stock" msgstr "有庫存" -#: company/models.py:124 +#: company/models.py:125 msgid "Companies" msgstr "公司" -#: company/models.py:152 +#: company/models.py:153 msgid "Company description" msgstr "公司簡介" -#: company/models.py:153 +#: company/models.py:154 msgid "Description of the company" msgstr "公司簡介" -#: company/models.py:159 +#: company/models.py:160 msgid "Website" msgstr "網站" -#: company/models.py:160 +#: company/models.py:161 msgid "Company website URL" msgstr "公司網站" -#: company/models.py:166 +#: company/models.py:167 msgid "Phone number" msgstr "電話號碼" -#: company/models.py:168 +#: company/models.py:169 msgid "Contact phone number" msgstr "聯繫電話" -#: company/models.py:175 +#: company/models.py:176 msgid "Contact email address" msgstr "聯繫人電子郵箱地址" -#: company/models.py:180 company/models.py:306 order/models.py:516 -#: users/models.py:561 +#: company/models.py:181 company/models.py:311 order/models.py:525 +#: users/models.py:559 msgid "Contact" msgstr "聯繫人" -#: company/models.py:182 +#: company/models.py:183 msgid "Point of contact" msgstr "聯絡點" -#: company/models.py:188 +#: company/models.py:189 msgid "Link to external company information" msgstr "外部公司信息鏈接" -#: company/models.py:193 +#: company/models.py:194 msgid "Is this company active?" msgstr "這家公司是否激活?" -#: company/models.py:198 +#: company/models.py:199 msgid "Is customer" msgstr "是客户" -#: company/models.py:199 +#: company/models.py:200 msgid "Do you sell items to this company?" msgstr "你是否向該公司出售商品?" -#: company/models.py:204 +#: company/models.py:205 msgid "Is supplier" msgstr "是否為供應商" -#: company/models.py:205 +#: company/models.py:206 msgid "Do you purchase items from this company?" msgstr "你從這家公司買東西嗎?" -#: company/models.py:210 +#: company/models.py:211 msgid "Is manufacturer" msgstr "是製造商嗎" -#: company/models.py:211 +#: company/models.py:212 msgid "Does this company manufacture parts?" msgstr "這家公司生產零件嗎?" -#: company/models.py:219 +#: company/models.py:220 msgid "Default currency used for this company" msgstr "此公司使用的默認貨幣" -#: company/models.py:226 +#: company/models.py:227 msgid "Tax ID" msgstr "稅籍編號" -#: company/models.py:227 +#: company/models.py:228 msgid "Company Tax ID" msgstr "公司稅籍編號" -#: company/models.py:345 order/models.py:526 order/models.py:2290 +#: company/models.py:350 order/models.py:535 order/models.py:2371 msgid "Address" msgstr "地址" -#: company/models.py:346 +#: company/models.py:351 msgid "Addresses" msgstr "地址" -#: company/models.py:400 +#: company/models.py:405 msgid "Select company" msgstr "選擇公司" -#: company/models.py:405 +#: company/models.py:410 msgid "Address title" msgstr "地址標題" -#: company/models.py:406 +#: company/models.py:411 msgid "Title describing the address entry" msgstr "描述地址條目的標題" -#: company/models.py:412 +#: company/models.py:417 msgid "Primary address" msgstr "主要地址" -#: company/models.py:413 +#: company/models.py:418 msgid "Set as primary address" msgstr "設置主要地址" -#: company/models.py:418 +#: company/models.py:423 msgid "Line 1" msgstr "第1行" -#: company/models.py:419 +#: company/models.py:424 msgid "Address line 1" msgstr "地址行1" -#: company/models.py:425 +#: company/models.py:430 msgid "Line 2" msgstr "第2行" -#: company/models.py:426 +#: company/models.py:431 msgid "Address line 2" msgstr "地址行2" -#: company/models.py:432 company/models.py:433 +#: company/models.py:437 company/models.py:438 msgid "Postal code" msgstr "郵政編碼" -#: company/models.py:439 +#: company/models.py:444 msgid "City/Region" msgstr "城市/地區" -#: company/models.py:440 +#: company/models.py:445 msgid "Postal code city/region" msgstr "郵政編碼城市/地區" -#: company/models.py:446 +#: company/models.py:451 msgid "State/Province" msgstr "省/市/自治區" -#: company/models.py:447 +#: company/models.py:452 msgid "State or province" msgstr "省、自治區或直轄市" -#: company/models.py:453 +#: company/models.py:458 msgid "Country" msgstr "國家/地區" -#: company/models.py:454 +#: company/models.py:459 msgid "Address country" msgstr "地址所在國家" -#: company/models.py:460 +#: company/models.py:465 msgid "Courier shipping notes" msgstr "快遞運單" -#: company/models.py:461 +#: company/models.py:466 msgid "Notes for shipping courier" msgstr "運輸快遞注意事項" -#: company/models.py:467 +#: company/models.py:472 msgid "Internal shipping notes" msgstr "內部裝運通知單" -#: company/models.py:468 +#: company/models.py:473 msgid "Shipping notes for internal use" msgstr "內部使用的裝運通知單" -#: company/models.py:475 +#: company/models.py:480 msgid "Link to address information (external)" msgstr "鏈接地址信息 (外部)" -#: company/models.py:502 company/models.py:797 company/serializers.py:475 -#: stock/api.py:561 +#: company/models.py:507 company/models.py:802 company/serializers.py:474 +#: stock/api.py:560 msgid "Manufacturer Part" msgstr "製造商零件" -#: company/models.py:519 company/models.py:759 stock/models.py:1030 -#: stock/serializers.py:409 +#: company/models.py:524 company/models.py:764 stock/models.py:1056 +#: stock/serializers.py:418 msgid "Base Part" msgstr "基礎零件" -#: company/models.py:521 company/models.py:761 +#: company/models.py:526 company/models.py:766 msgid "Select part" msgstr "選擇零件" -#: company/models.py:531 +#: company/models.py:536 msgid "Select manufacturer" msgstr "選擇製造商" -#: company/models.py:537 company/serializers.py:486 order/serializers.py:692 -#: part/serializers.py:488 +#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 +#: part/serializers.py:499 msgid "MPN" msgstr "製造商零件編號" -#: company/models.py:538 stock/serializers.py:564 +#: company/models.py:543 stock/serializers.py:578 msgid "Manufacturer Part Number" msgstr "製造商零件編號" -#: company/models.py:545 +#: company/models.py:550 msgid "URL for external manufacturer part link" msgstr "外部製造商零件鏈接的URL" -#: company/models.py:554 +#: company/models.py:559 msgid "Manufacturer part description" msgstr "製造商零件説明" -#: company/models.py:686 +#: company/models.py:691 msgid "Pack units must be compatible with the base part units" msgstr "包裝單位必須與基礎零件單位兼容" -#: company/models.py:693 +#: company/models.py:698 msgid "Pack units must be greater than zero" msgstr "包裝單位必須大於零" -#: company/models.py:707 +#: company/models.py:712 msgid "Linked manufacturer part must reference the same base part" msgstr "鏈接的製造商零件必須引用相同的基礎零件" -#: company/models.py:769 company/serializers.py:443 company/serializers.py:470 -#: order/models.py:642 part/serializers.py:462 +#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 +#: order/models.py:666 part/serializers.py:473 #: 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:567 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "供應商" -#: company/models.py:770 +#: company/models.py:775 msgid "Select supplier" msgstr "選擇供應商" -#: company/models.py:776 part/serializers.py:473 +#: company/models.py:781 part/serializers.py:484 msgid "Supplier stock keeping unit" msgstr "供應商庫存管理單位" -#: company/models.py:782 +#: company/models.py:787 msgid "Is this supplier part active?" msgstr "此供應商零件是否處於活動狀態?" -#: company/models.py:787 +#: company/models.py:792 msgid "Primary" -msgstr "" +msgstr "主要" -#: company/models.py:788 +#: company/models.py:793 msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgstr "這是關聯零件的主要供應商零件嗎?" -#: company/models.py:798 +#: company/models.py:803 msgid "Select manufacturer part" msgstr "選擇製造商零件" -#: company/models.py:805 +#: company/models.py:810 msgid "URL for external supplier part link" msgstr "外部供應商零件鏈接的URL" -#: company/models.py:814 +#: company/models.py:819 msgid "Supplier part description" msgstr "供應商零件説明" -#: company/models.py:830 part/models.py:2301 +#: company/models.py:835 part/models.py:2310 msgid "base cost" msgstr "基本費用" -#: company/models.py:831 part/models.py:2302 +#: company/models.py:836 part/models.py:2311 msgid "Minimum charge (e.g. stocking fee)" msgstr "最低費用(例如庫存費)" -#: company/models.py:838 order/serializers.py:833 stock/models.py:1061 -#: stock/serializers.py:1637 +#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 +#: stock/serializers.py:1681 msgid "Packaging" msgstr "打包" -#: company/models.py:839 +#: company/models.py:844 msgid "Part packaging" msgstr "零件打包" -#: company/models.py:844 +#: company/models.py:849 msgid "Pack Quantity" msgstr "包裝數量" -#: company/models.py:846 +#: company/models.py:851 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "單包供應的總數量。為單個項目留空。" -#: company/models.py:865 part/models.py:2308 +#: company/models.py:870 part/models.py:2317 msgid "multiple" msgstr "多個" -#: company/models.py:866 +#: company/models.py:871 msgid "Order multiple" msgstr "訂購多個" -#: company/models.py:878 +#: company/models.py:883 msgid "Quantity available from supplier" msgstr "供應商提供的數量" -#: company/models.py:884 +#: company/models.py:889 msgid "Availability Updated" msgstr "可用性已更新" -#: company/models.py:885 +#: company/models.py:890 msgid "Date of last update of availability data" msgstr "上次更新可用性數據的日期" -#: company/models.py:1013 +#: company/models.py:1018 msgid "Supplier Price Break" msgstr "供應商批發價" -#: company/serializers.py:191 +#: company/serializers.py:185 msgid "Default currency used for this supplier" msgstr "此供應商使用的默認貨幣" -#: company/serializers.py:229 +#: company/serializers.py:202 msgid "Company Name" msgstr "公司名稱" -#: company/serializers.py:407 part/serializers.py:827 stock/serializers.py:430 +#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 msgid "In Stock" msgstr "有庫存" -#: company/serializers.py:424 +#: company/serializers.py:408 msgid "Price Breaks" -msgstr "" +msgstr "價格折扣" + +#: company/serializers.py:461 +msgid "Pretty Name" +msgstr "顯示名稱" #: data_exporter/mixins.py:328 data_exporter/mixins.py:417 msgid "Error occurred during data export" @@ -4428,69 +4528,69 @@ msgstr "ID" msgid "Existing database identifier for the record" msgstr "資料庫中既有紀錄的識別碼" -#: importer/models.py:452 +#: importer/models.py:459 msgid "Column is already mapped to a database field" msgstr "列已映射到數據庫字段" -#: importer/models.py:457 +#: importer/models.py:464 msgid "Field is already mapped to a data column" msgstr "字段已映射到數據列" -#: importer/models.py:466 +#: importer/models.py:473 msgid "Column mapping must be linked to a valid import session" msgstr "列映射必須鏈接到有效的導入會話" -#: importer/models.py:471 +#: importer/models.py:478 msgid "Column does not exist in the data file" msgstr "數據文件中不存在列" -#: importer/models.py:478 +#: importer/models.py:485 msgid "Field does not exist in the target model" msgstr "目標模型中不存在字段" -#: importer/models.py:482 +#: importer/models.py:489 msgid "Selected field is read-only" msgstr "所選字段為只讀" -#: importer/models.py:487 importer/models.py:558 +#: importer/models.py:494 importer/models.py:571 msgid "Import Session" msgstr "導入會話" -#: importer/models.py:491 +#: importer/models.py:498 msgid "Field" msgstr "字段" -#: importer/models.py:493 +#: importer/models.py:500 msgid "Column" msgstr "列" -#: importer/models.py:562 +#: importer/models.py:575 msgid "Row Index" msgstr "行索引" -#: importer/models.py:565 +#: importer/models.py:578 msgid "Original row data" msgstr "原始行數據" -#: importer/models.py:570 machine/models.py:111 +#: importer/models.py:583 machine/models.py:111 msgid "Errors" msgstr "錯誤" -#: importer/models.py:572 part/serializers.py:1114 +#: importer/models.py:585 part/serializers.py:1148 msgid "Valid" msgstr "有效" -#: importer/models.py:833 +#: importer/models.py:846 msgid "ID is required for updating existing records." msgstr "更新既有紀錄需要提供 ID。" -#: importer/models.py:840 +#: importer/models.py:853 msgid "No record found with the provided ID" -msgstr "" +msgstr "找不到提供 ID 的記錄" -#: importer/models.py:846 +#: importer/models.py:859 msgid "Invalid ID format provided" -msgstr "" +msgstr "提供的 ID 格式無效" #: importer/operations.py:31 importer/operations.py:52 msgid "Unsupported data file format" @@ -4588,7 +4688,7 @@ msgstr "每個標籤要打印的份數" msgid "Connected" msgstr "已連接" -#: machine/machine_types/label_printer.py:232 order/api.py:1805 +#: machine/machine_types/label_printer.py:232 order/api.py:1848 msgid "Unknown" msgstr "未知" @@ -4598,7 +4698,7 @@ msgstr "正在打印" #: machine/machine_types/label_printer.py:234 msgid "Warning" -msgstr "" +msgstr "警告" #: machine/machine_types/label_printer.py:235 msgid "No media" @@ -4614,7 +4714,7 @@ msgstr "已斷開連接" #: machine/machine_types/label_printer.py:238 msgid "Error" -msgstr "" +msgstr "錯誤" #: machine/machine_types/label_printer.py:245 msgid "Label Printer" @@ -4686,41 +4786,41 @@ msgstr "配置類型" #: machine/serializers.py:24 msgid "Key of the property" -msgstr "" +msgstr "屬性鍵值" #: machine/serializers.py:27 msgid "Value of the property" -msgstr "" +msgstr "屬性值" -#: machine/serializers.py:30 users/models.py:238 +#: machine/serializers.py:30 users/models.py:236 msgid "Group" msgstr "組" #: machine/serializers.py:30 msgid "Grouping of the property" -msgstr "" +msgstr "屬性分組" #: machine/serializers.py:33 msgid "Type" -msgstr "" +msgstr "類型" #: machine/serializers.py:35 msgid "Type of the property" -msgstr "" +msgstr "屬性類別" #: machine/serializers.py:40 msgid "Max Progress" -msgstr "" +msgstr "最大進度" #: machine/serializers.py:41 msgid "Maximum value for progress type, required if type=progress" -msgstr "" +msgstr "進度類型的最大值,當 type=progress 時為必填" #: order/api.py:130 msgid "Order Reference" msgstr "訂單參考" -#: order/api.py:158 order/api.py:1206 +#: order/api.py:158 order/api.py:1220 msgid "Outstanding" msgstr "未完成" @@ -4728,7 +4828,7 @@ msgstr "未完成" msgid "Has Project Code" msgstr "有項目編碼" -#: order/api.py:188 order/models.py:491 +#: order/api.py:188 order/models.py:493 msgid "Created By" msgstr "創建人" @@ -4764,57 +4864,69 @@ msgstr "目標日期早於" msgid "Target Date After" msgstr "目標日期晚於" -#: order/api.py:279 +#: order/api.py:232 +msgid "Updated Before" +msgstr "更新之前" + +#: order/api.py:236 +msgid "Updated After" +msgstr "更新之後" + +#: order/api.py:287 msgid "Has Pricing" msgstr "有定價" -#: order/api.py:332 order/api.py:816 order/api.py:1489 +#: order/api.py:340 order/api.py:827 order/api.py:1529 msgid "Completed Before" msgstr "完成時間早於" -#: order/api.py:336 order/api.py:820 order/api.py:1493 +#: order/api.py:344 order/api.py:831 order/api.py:1533 msgid "Completed After" msgstr "完成時間晚於" -#: order/api.py:342 order/api.py:346 +#: order/api.py:350 order/api.py:354 msgid "External Build Order" msgstr "外部生產工單" -#: order/api.py:530 order/api.py:915 order/api.py:1169 order/models.py:1925 -#: order/models.py:2051 order/models.py:2101 order/models.py:2281 -#: order/models.py:2479 order/models.py:3006 order/models.py:3072 +#: 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 msgid "Order" msgstr "訂單" -#: order/api.py:534 order/api.py:983 +#: order/api.py:543 order/api.py:995 msgid "Order Complete" msgstr "訂單完成" -#: order/api.py:566 order/api.py:570 order/serializers.py:703 +#: order/api.py:575 order/api.py:579 order/serializers.py:754 msgid "Internal Part" msgstr "內部零件" -#: order/api.py:588 +#: order/api.py:597 msgid "Order Pending" msgstr "訂單待定" -#: order/api.py:968 +#: order/api.py:980 msgid "Completed" msgstr "已完成" -#: order/api.py:1222 +#: order/api.py:1236 msgid "Has Shipment" msgstr "已出貨" -#: order/api.py:1799 order/models.py:555 order/models.py:1926 -#: order/models.py:2052 +#: order/api.py:1444 +msgid "Shipment not found" +msgstr "找不到發貨紀錄" + +#: order/api.py:1842 order/models.py:577 order/models.py:2004 +#: order/models.py:2130 #: report/templates/report/inventree_purchase_order_report.html:14 #: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "採購訂單" -#: order/api.py:1801 order/models.py:1254 order/models.py:2102 -#: order/models.py:2282 order/models.py:2480 +#: order/api.py:1844 order/models.py:1292 order/models.py:2182 +#: order/models.py:2363 order/models.py:2559 #: 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 @@ -4822,8 +4934,8 @@ msgstr "採購訂單" msgid "Sales Order" msgstr "銷售訂單" -#: order/api.py:1803 order/models.py:2651 order/models.py:3007 -#: order/models.py:3073 +#: order/api.py:1846 order/models.py:2730 order/models.py:3088 +#: order/models.py:3154 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" @@ -4839,11 +4951,11 @@ msgstr "總價格" msgid "Total price for this order" msgstr "此訂單的總價" -#: order/models.py:96 order/serializers.py:67 +#: order/models.py:96 order/serializers.py:62 msgid "Order Currency" msgstr "訂單貨幣" -#: order/models.py:99 order/serializers.py:68 +#: order/models.py:99 order/serializers.py:63 msgid "Currency for this order (leave blank to use company default)" msgstr "此訂單的貨幣 (留空以使用公司默認值)" @@ -4851,718 +4963,750 @@ msgstr "此訂單的貨幣 (留空以使用公司默認值)" msgid "This order is locked and cannot be modified" msgstr "此訂單已鎖定,無法修改" -#: order/models.py:378 +#: order/models.py:380 msgid "Contact does not match selected company" msgstr "聯繫人與所選公司不匹配" -#: order/models.py:385 +#: order/models.py:387 msgid "Start date must be before target date" msgstr "開始日期必須早於目標日期" -#: order/models.py:392 +#: order/models.py:394 msgid "Address does not match selected company" -msgstr "" +msgstr "地址不符合選定的公司" -#: order/models.py:446 +#: order/models.py:448 msgid "Order description (optional)" msgstr "訂單描述 (可選)" -#: order/models.py:455 order/models.py:1809 +#: order/models.py:457 order/models.py:1871 msgid "Select project code for this order" msgstr "為此訂單選擇項目編碼" -#: order/models.py:461 order/models.py:1790 order/models.py:2346 +#: order/models.py:463 order/models.py:1852 order/models.py:2427 msgid "Link to external page" msgstr "鏈接到外部頁面" -#: order/models.py:468 +#: order/models.py:470 msgid "Start date" msgstr "開始日期" -#: order/models.py:469 +#: order/models.py:471 msgid "Scheduled start date for this order" msgstr "此訂單的預定開始日期" -#: order/models.py:475 order/models.py:1797 order/serializers.py:289 +#: order/models.py:477 order/models.py:1859 order/serializers.py:308 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "預計日期" -#: order/models.py:477 +#: order/models.py:479 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "訂單交付的預期日期。訂單將在此日期後過期。" -#: order/models.py:497 +#: order/models.py:499 msgid "Issue Date" msgstr "簽發日期" -#: order/models.py:498 +#: order/models.py:500 msgid "Date order was issued" msgstr "訂單發出日期" #: order/models.py:506 +msgid "Updated At" +msgstr "更新於" + +#: order/models.py:515 msgid "User or group responsible for this order" msgstr "負責此訂單的用户或組" -#: order/models.py:517 +#: order/models.py:526 msgid "Point of contact for this order" msgstr "此訂單的聯繫人" -#: order/models.py:527 +#: order/models.py:536 msgid "Company address for this order" msgstr "此訂單的公司地址" -#: order/models.py:618 order/models.py:1315 +#: order/models.py:642 order/models.py:1355 msgid "Order reference" msgstr "訂單參考" -#: order/models.py:627 order/models.py:1339 order/models.py:2739 -#: stock/serializers.py:551 stock/serializers.py:992 users/models.py:542 +#: order/models.py:651 order/models.py:1379 order/models.py:2820 +#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 msgid "Status" msgstr "狀態" -#: order/models.py:628 +#: order/models.py:652 msgid "Purchase order status" msgstr "採購訂單狀態" -#: order/models.py:643 +#: order/models.py:667 msgid "Company from which the items are being ordered" msgstr "訂購物品的公司" -#: order/models.py:654 +#: order/models.py:678 msgid "Supplier Reference" msgstr "供應商參考" -#: order/models.py:655 +#: order/models.py:679 msgid "Supplier order reference code" msgstr "供應商訂單參考代碼" -#: order/models.py:664 +#: order/models.py:688 msgid "received by" msgstr "接收人" -#: order/models.py:671 order/models.py:2754 +#: order/models.py:695 order/models.py:2835 msgid "Date order was completed" msgstr "訂單完成日期" -#: order/models.py:680 order/models.py:1984 +#: order/models.py:704 order/models.py:2062 msgid "Destination" msgstr "目的地" -#: order/models.py:681 order/models.py:1988 +#: order/models.py:705 order/models.py:2066 msgid "Destination for received items" msgstr "收到項目的存放目的地" -#: order/models.py:727 +#: order/models.py:751 msgid "Part supplier must match PO supplier" msgstr "零件供應商必須與採購訂單供應商匹配" -#: order/models.py:997 +#: order/models.py:1021 msgid "Line item does not match purchase order" msgstr "行項目與採購訂單不匹配" -#: order/models.py:1000 +#: order/models.py:1024 msgid "Line item is missing a linked part" msgstr "行項目缺少關聯零件" -#: order/models.py:1014 +#: order/models.py:1038 msgid "Quantity must be a positive number" msgstr "數量必須是正數" -#: order/models.py:1326 order/models.py:2726 stock/models.py:1083 -#: stock/models.py:1084 stock/serializers.py:1353 +#: order/models.py:1072 +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 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "客户" -#: order/models.py:1327 +#: order/models.py:1367 msgid "Company to which the items are being sold" msgstr "出售物品的公司" -#: order/models.py:1340 +#: order/models.py:1380 msgid "Sales order status" msgstr "銷售訂單狀態" -#: order/models.py:1351 order/models.py:2746 +#: order/models.py:1391 order/models.py:2827 msgid "Customer Reference " msgstr "客户參考 " -#: order/models.py:1352 order/models.py:2747 +#: order/models.py:1392 order/models.py:2828 msgid "Customer order reference code" msgstr "客户訂單參考代碼" -#: order/models.py:1356 order/models.py:2298 +#: order/models.py:1396 order/models.py:2379 msgid "Shipment Date" msgstr "發貨日期" -#: order/models.py:1365 +#: order/models.py:1405 msgid "shipped by" msgstr "發貨人" -#: order/models.py:1416 +#: order/models.py:1456 msgid "Order is already complete" msgstr "訂單已完成" -#: order/models.py:1419 +#: order/models.py:1459 msgid "Order is already cancelled" msgstr "訂單已取消" -#: order/models.py:1423 +#: order/models.py:1463 msgid "Only an open order can be marked as complete" msgstr "只有未結訂單才能標記為已完成" -#: order/models.py:1427 +#: order/models.py:1467 msgid "Order cannot be completed as there are incomplete shipments" msgstr "由於發貨不完整,訂單無法完成" -#: order/models.py:1432 +#: order/models.py:1472 msgid "Order cannot be completed as there are incomplete allocations" msgstr "訂單無法完成,因為仍有未完成的分配" -#: order/models.py:1441 +#: order/models.py:1481 msgid "Order cannot be completed as there are incomplete line items" msgstr "訂單無法完成,因為行項目不完整" -#: order/models.py:1736 order/models.py:1752 +#: order/models.py:1778 order/models.py:1803 msgid "The order is locked and cannot be modified" msgstr "此訂單已鎖定,無法修改" -#: order/models.py:1760 +#: order/models.py:1811 msgid "Item quantity" msgstr "項目數量" -#: order/models.py:1777 +#: order/models.py:1829 +msgid "Line Number" +msgstr "行號" + +#: order/models.py:1830 +msgid "Line number for this item (optional)" +msgstr "此項目的行號 (選填)" + +#: order/models.py:1839 msgid "Line item reference" msgstr "行項目參考" -#: order/models.py:1784 +#: order/models.py:1846 msgid "Line item notes" msgstr "行項目註釋" -#: order/models.py:1799 +#: order/models.py:1861 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "此行項目的目標日期 (留空以使用訂單中的目標日期)" -#: order/models.py:1829 +#: order/models.py:1891 msgid "Line item description (optional)" msgstr "行項目描述 (可選)" -#: order/models.py:1836 +#: order/models.py:1898 msgid "Additional context for this line" msgstr "此行的附加上下文" -#: order/models.py:1846 +#: order/models.py:1908 msgid "Unit price" msgstr "單位價格" -#: order/models.py:1865 +#: order/models.py:1927 msgid "Purchase Order Line Item" msgstr "採購訂單行項目" -#: order/models.py:1892 +#: order/models.py:1956 msgid "Supplier part must match supplier" msgstr "供應商零件必須與供應商匹配" -#: order/models.py:1897 +#: order/models.py:1964 msgid "Build order must be marked as external" msgstr "生產工單必須標記為外部" -#: order/models.py:1904 +#: order/models.py:1971 msgid "Build orders can only be linked to assembly parts" msgstr "生產工單只能連結到組裝零件" -#: order/models.py:1910 +#: order/models.py:1977 msgid "Build order part must match line item part" msgstr "生產工單的零件必須與行項目的零件一致" -#: order/models.py:1945 +#: 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:1952 +#: order/models.py:2030 msgid "Received" msgstr "已接收" -#: order/models.py:1953 +#: order/models.py:2031 msgid "Number of items received" msgstr "收到的物品數量" -#: order/models.py:1961 stock/models.py:1206 stock/serializers.py:641 +#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 msgid "Purchase Price" msgstr "採購價格" -#: order/models.py:1962 +#: order/models.py:2040 msgid "Unit purchase price" msgstr "每單位的採購價格" -#: order/models.py:1978 +#: order/models.py:2056 msgid "External Build Order to be fulfilled by this line item" msgstr "由此行項目履行的外部生產工單" -#: order/models.py:2040 +#: order/models.py:2118 msgid "Purchase Order Extra Line" msgstr "採購訂單附加行" -#: order/models.py:2069 +#: order/models.py:2147 msgid "Sales Order Line Item" msgstr "銷售訂單行項目" -#: order/models.py:2094 +#: order/models.py:2174 msgid "Only salable parts can be assigned to a sales order" msgstr "只有可銷售的零件才能分配給銷售訂單" -#: order/models.py:2120 +#: order/models.py:2200 msgid "Sale Price" msgstr "售出價格" -#: order/models.py:2121 +#: order/models.py:2201 msgid "Unit sale price" msgstr "單位售出價格" -#: order/models.py:2130 order/status_codes.py:50 +#: order/models.py:2210 order/status_codes.py:50 msgid "Shipped" msgstr "已配送" -#: order/models.py:2131 +#: order/models.py:2211 msgid "Shipped quantity" msgstr "發貨數量" -#: order/models.py:2242 +#: order/models.py:2323 msgid "Sales Order Shipment" msgstr "銷售訂單發貨" -#: order/models.py:2255 +#: order/models.py:2336 msgid "Shipment address must match the customer" -msgstr "" +msgstr "配送地址必須跟客戶相符" -#: order/models.py:2291 +#: order/models.py:2372 msgid "Shipping address for this shipment" -msgstr "" +msgstr "配送的採購地址" -#: order/models.py:2299 +#: order/models.py:2380 msgid "Date of shipment" msgstr "發貨日期" -#: order/models.py:2305 +#: order/models.py:2386 msgid "Delivery Date" msgstr "送達日期" -#: order/models.py:2306 +#: order/models.py:2387 msgid "Date of delivery of shipment" msgstr "裝運交貨日期" -#: order/models.py:2314 +#: order/models.py:2395 msgid "Checked By" msgstr "審核人" -#: order/models.py:2315 +#: order/models.py:2396 msgid "User who checked this shipment" msgstr "檢查此裝運的用户" -#: order/models.py:2322 order/models.py:2576 order/serializers.py:1707 -#: order/serializers.py:1831 +#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 +#: order/serializers.py:1942 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "配送" -#: order/models.py:2323 +#: order/models.py:2404 msgid "Shipment number" msgstr "配送單號" -#: order/models.py:2331 +#: order/models.py:2412 msgid "Tracking Number" msgstr "跟蹤單號" -#: order/models.py:2332 +#: order/models.py:2413 msgid "Shipment tracking information" msgstr "配送跟蹤信息" -#: order/models.py:2339 +#: order/models.py:2420 msgid "Invoice Number" msgstr "發票編號" -#: order/models.py:2340 +#: order/models.py:2421 msgid "Reference number for associated invoice" msgstr "相關發票的參考號" -#: order/models.py:2379 +#: order/models.py:2467 msgid "Shipment has already been sent" msgstr "貨物已發出" -#: order/models.py:2382 +#: order/models.py:2470 msgid "Shipment has no allocated stock items" msgstr "發貨沒有分配庫存項目" -#: order/models.py:2389 +#: order/models.py:2477 msgid "Shipment must be checked before it can be completed" -msgstr "" +msgstr "發貨紀錄必須在完成前進行檢查" -#: order/models.py:2468 +#: order/models.py:2547 msgid "Sales Order Extra Line" msgstr "銷售訂單加行" -#: order/models.py:2497 +#: order/models.py:2576 msgid "Sales Order Allocation" msgstr "銷售訂單分配" -#: order/models.py:2520 order/models.py:2522 +#: order/models.py:2599 order/models.py:2601 msgid "Stock item has not been assigned" msgstr "庫存項目尚未分配" -#: order/models.py:2529 +#: order/models.py:2608 msgid "Cannot allocate stock item to a line with a different part" msgstr "無法將庫存項目分配給具有不同零件的行" -#: order/models.py:2532 +#: order/models.py:2611 msgid "Cannot allocate stock to a line without a part" msgstr "無法將庫存分配給沒有零件的生產線" -#: order/models.py:2535 +#: order/models.py:2614 msgid "Allocation quantity cannot exceed stock quantity" msgstr "分配數量不能超過庫存數量" -#: order/models.py:2551 +#: order/models.py:2630 msgid "Allocation quantity must be greater than zero" msgstr "分配的數量必須大於零" -#: order/models.py:2554 order/serializers.py:1577 +#: order/models.py:2633 order/serializers.py:1678 msgid "Quantity must be 1 for serialized stock item" msgstr "序列化庫存項目的數量必須為1" -#: order/models.py:2557 +#: order/models.py:2636 msgid "Sales order does not match shipment" msgstr "銷售訂單與發貨不匹配" -#: order/models.py:2558 plugin/base/barcodes/api.py:643 +#: order/models.py:2637 plugin/base/barcodes/api.py:643 msgid "Shipment does not match sales order" msgstr "發貨與銷售訂單不匹配" -#: order/models.py:2566 +#: order/models.py:2645 msgid "Line" msgstr "行" -#: order/models.py:2577 +#: order/models.py:2656 msgid "Sales order shipment reference" msgstr "銷售訂單發貨參考" -#: order/models.py:2590 order/models.py:3014 +#: order/models.py:2669 order/models.py:3095 msgid "Item" msgstr "項目" -#: order/models.py:2591 +#: order/models.py:2670 msgid "Select stock item to allocate" msgstr "選擇要分配的庫存項目" -#: order/models.py:2600 +#: order/models.py:2679 msgid "Enter stock allocation quantity" msgstr "輸入庫存分配數量" -#: order/models.py:2715 +#: order/models.py:2796 msgid "Return Order reference" msgstr "退貨訂單參考" -#: order/models.py:2727 +#: order/models.py:2808 msgid "Company from which items are being returned" msgstr "退回物品的公司" -#: order/models.py:2740 +#: order/models.py:2821 msgid "Return order status" msgstr "退貨訂單狀態" -#: order/models.py:2972 +#: order/models.py:3053 msgid "Return Order Line Item" msgstr "退貨訂單行項目" -#: order/models.py:2985 +#: order/models.py:3066 msgid "Stock item must be specified" msgstr "必須指定庫存項目" -#: order/models.py:2989 +#: order/models.py:3070 msgid "Return quantity exceeds stock quantity" msgstr "退回數量超過庫存數量" -#: order/models.py:2994 +#: order/models.py:3075 msgid "Return quantity must be greater than zero" msgstr "退回數量必須大於零" -#: order/models.py:2999 +#: order/models.py:3080 msgid "Invalid quantity for serialized stock item" msgstr "序列化庫存項目的數量無效" -#: order/models.py:3015 +#: order/models.py:3096 msgid "Select item to return from customer" msgstr "選擇要從客户處退回的商品" -#: order/models.py:3030 +#: order/models.py:3111 msgid "Received Date" msgstr "接收日期" -#: order/models.py:3031 +#: order/models.py:3112 msgid "The date this return item was received" -msgstr "" +msgstr "收到此退貨項目的日期" -#: order/models.py:3043 +#: order/models.py:3124 msgid "Outcome" msgstr "結果" -#: order/models.py:3044 +#: order/models.py:3125 msgid "Outcome for this line item" msgstr "該行項目的結果" -#: order/models.py:3051 +#: order/models.py:3132 msgid "Cost associated with return or repair for this line item" msgstr "與此行項目的退貨或維修相關的成本" -#: order/models.py:3061 +#: order/models.py:3142 msgid "Return Order Extra Line" msgstr "退貨訂單附加行" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "Order ID" msgstr "訂單ID" -#: order/serializers.py:81 +#: order/serializers.py:76 msgid "ID of the order to duplicate" msgstr "要複製的訂單ID" -#: order/serializers.py:87 +#: order/serializers.py:82 msgid "Copy Lines" msgstr "複製行" -#: order/serializers.py:88 +#: order/serializers.py:83 msgid "Copy line items from the original order" msgstr "從原始訂單複製行項目" -#: order/serializers.py:94 +#: order/serializers.py:89 msgid "Copy Extra Lines" msgstr "複製額外行" -#: order/serializers.py:95 +#: order/serializers.py:90 msgid "Copy extra line items from the original order" msgstr "從原始訂單複製額外的行項目" -#: order/serializers.py:110 +#: 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 #: 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 msgid "Line Items" msgstr "行項目" -#: order/serializers.py:115 +#: order/serializers.py:117 msgid "Completed Lines" msgstr "已完成行項目" -#: order/serializers.py:171 +#: order/serializers.py:185 msgid "Duplicate Order" msgstr "複製訂單" -#: order/serializers.py:172 +#: order/serializers.py:186 msgid "Specify options for duplicating this order" msgstr "指定複製此訂單的選項" -#: order/serializers.py:250 +#: order/serializers.py:265 msgid "Invalid order ID" msgstr "訂單ID不正確" -#: order/serializers.py:419 +#: order/serializers.py:445 msgid "Supplier Name" msgstr "供應商名稱" -#: order/serializers.py:464 +#: order/serializers.py:494 msgid "Order cannot be cancelled" msgstr "訂單不能取消" -#: order/serializers.py:479 order/serializers.py:1598 +#: order/serializers.py:509 order/serializers.py:1699 msgid "Allow order to be closed with incomplete line items" msgstr "允許關閉行項目不完整的訂單" -#: order/serializers.py:489 order/serializers.py:1608 +#: order/serializers.py:519 order/serializers.py:1709 msgid "Order has incomplete line items" msgstr "訂單中的行項目不完整" -#: order/serializers.py:609 +#: order/serializers.py:639 msgid "Order is not open" msgstr "訂單未打開" -#: order/serializers.py:638 +#: order/serializers.py:677 msgid "Auto Pricing" msgstr "自動定價" -#: order/serializers.py:640 +#: order/serializers.py:679 msgid "Automatically calculate purchase price based on supplier part data" msgstr "根據供應商零件數據自動計算採購價格" -#: order/serializers.py:654 +#: order/serializers.py:696 msgid "Purchase price currency" msgstr "購買價格貨幣" -#: order/serializers.py:676 +#: order/serializers.py:727 msgid "Merge Items" msgstr "合併項目" -#: order/serializers.py:678 +#: order/serializers.py:729 msgid "Merge items with the same part, destination and target date into one line item" msgstr "將具有相同零件、目的地和目標日期的項目合併到一個行項目中" -#: order/serializers.py:685 part/serializers.py:472 +#: order/serializers.py:736 part/serializers.py:483 msgid "SKU" msgstr "庫存量單位" -#: order/serializers.py:699 part/models.py:1157 part/serializers.py:338 +#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 msgid "Internal Part Number" msgstr "內部零件編號" -#: order/serializers.py:707 +#: order/serializers.py:758 msgid "Internal Part Name" msgstr "內部零件名稱" -#: order/serializers.py:723 +#: order/serializers.py:774 msgid "Supplier part must be specified" msgstr "必須指定供應商零件" -#: order/serializers.py:726 +#: order/serializers.py:777 msgid "Purchase order must be specified" msgstr "必須指定採購訂單" -#: order/serializers.py:734 +#: order/serializers.py:785 msgid "Supplier must match purchase order" msgstr "供應商必須匹配採購訂單" -#: order/serializers.py:735 +#: order/serializers.py:786 msgid "Purchase order must match supplier" msgstr "採購訂單必須與供應商匹配" -#: order/serializers.py:783 order/serializers.py:1678 +#: order/serializers.py:838 order/serializers.py:1779 msgid "Line Item" msgstr "行項目" -#: order/serializers.py:792 order/serializers.py:932 order/serializers.py:2040 +#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 msgid "Select destination location for received items" msgstr "為收到的物品選擇目的地位置" -#: order/serializers.py:808 +#: order/serializers.py:863 msgid "Enter batch code for incoming stock items" msgstr "輸入入庫項目的批號" -#: order/serializers.py:815 stock/models.py:1165 +#: order/serializers.py:870 stock/models.py:1191 #: templates/email/stale_stock_notification.html:22 users/models.py:137 msgid "Expiry Date" msgstr "有效期至" -#: order/serializers.py:816 +#: order/serializers.py:871 msgid "Enter expiry date for incoming stock items" msgstr "輸入入庫庫存項目的到期日" -#: order/serializers.py:824 +#: order/serializers.py:879 msgid "Enter serial numbers for incoming stock items" msgstr "輸入入庫庫存項目的序列號" -#: order/serializers.py:834 +#: order/serializers.py:889 msgid "Override packaging information for incoming stock items" msgstr "覆蓋傳入庫存項目的包裝資料" -#: order/serializers.py:842 order/serializers.py:2045 +#: order/serializers.py:897 order/serializers.py:2165 msgid "Additional note for incoming stock items" msgstr "傳入庫存項目的附加説明" -#: order/serializers.py:849 +#: order/serializers.py:904 msgid "Barcode" msgstr "條形碼" -#: order/serializers.py:850 +#: order/serializers.py:905 msgid "Scanned barcode" msgstr "掃描條形碼" -#: order/serializers.py:866 +#: order/serializers.py:921 msgid "Barcode is already in use" msgstr "條形碼已被使用" -#: order/serializers.py:949 order/serializers.py:2064 +#: order/serializers.py:1004 order/serializers.py:2184 msgid "Line items must be provided" msgstr "必須提供行項目" -#: order/serializers.py:968 +#: order/serializers.py:1023 msgid "Destination location must be specified" msgstr "必須指定目標位置" -#: order/serializers.py:975 +#: order/serializers.py:1030 msgid "Supplied barcode values must be unique" msgstr "提供的條形碼值必須是唯一的" -#: order/serializers.py:1095 +#: order/serializers.py:1155 msgid "Shipments" msgstr "配送紀錄" -#: order/serializers.py:1099 +#: order/serializers.py:1159 msgid "Completed Shipments" msgstr "完成配送" -#: order/serializers.py:1103 +#: order/serializers.py:1163 msgid "Allocated Lines" -msgstr "" +msgstr "已分配行" -#: order/serializers.py:1282 +#: order/serializers.py:1356 msgid "Sale price currency" msgstr "售出價格貨幣" -#: order/serializers.py:1325 +#: order/serializers.py:1403 msgid "Allocated Items" msgstr "已分配項目" -#: order/serializers.py:1480 +#: order/serializers.py:1601 msgid "No shipment details provided" msgstr "未提供裝運詳細信息" -#: order/serializers.py:1541 order/serializers.py:1687 +#: order/serializers.py:1633 order/serializers.py:1788 msgid "Line item is not associated with this order" msgstr "行項目與此訂單不關聯" -#: order/serializers.py:1560 +#: order/serializers.py:1652 msgid "Quantity must be positive" msgstr "數量必須為正" -#: order/serializers.py:1697 +#: order/serializers.py:1673 +msgid "Stock item has not passed all required tests" +msgstr "" + +#: order/serializers.py:1798 msgid "Enter serial numbers to allocate" msgstr "輸入要分配的序列號" -#: order/serializers.py:1719 order/serializers.py:1839 +#: order/serializers.py:1820 order/serializers.py:1950 msgid "Shipment has already been shipped" msgstr "貨物已發出" -#: order/serializers.py:1722 order/serializers.py:1842 +#: order/serializers.py:1823 order/serializers.py:1953 msgid "Shipment is not associated with this order" msgstr "發貨與此訂單無關" -#: order/serializers.py:1777 +#: order/serializers.py:1886 msgid "No match found for the following serial numbers" msgstr "未找到以下序列號的匹配項" -#: order/serializers.py:1784 +#: order/serializers.py:1893 msgid "The following serial numbers are unavailable" msgstr "以下序列號不可用" -#: order/serializers.py:2006 +#: order/serializers.py:2126 msgid "Return order line item" msgstr "退貨訂單行項目" -#: order/serializers.py:2016 +#: order/serializers.py:2136 msgid "Line item does not match return order" msgstr "行項目與退貨訂單不匹配" -#: order/serializers.py:2019 +#: order/serializers.py:2139 msgid "Line item has already been received" msgstr "行項目已收到" -#: order/serializers.py:2056 +#: order/serializers.py:2176 msgid "Items can only be received against orders which are in progress" msgstr "只能根據正在進行的訂單接收物品" -#: order/serializers.py:2128 +#: order/serializers.py:2252 msgid "Quantity to return" msgstr "退回數量" -#: order/serializers.py:2145 +#: order/serializers.py:2277 msgid "Line price currency" msgstr "行價格貨幣" @@ -5598,146 +5742,150 @@ msgstr "退款" msgid "Reject" msgstr "拒絕" -#: order/tasks.py:47 +#: order/tasks.py:48 msgid "Overdue Purchase Order" msgstr "逾期採購訂單" -#: order/tasks.py:52 +#: order/tasks.py:53 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "採購訂單 {po} 已逾期" -#: order/tasks.py:117 +#: order/tasks.py:118 msgid "Overdue Sales Order" msgstr "逾期銷售訂單" -#: order/tasks.py:122 +#: order/tasks.py:123 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "銷售訂單 {so} 已逾期" -#: order/tasks.py:184 +#: order/tasks.py:185 msgid "Overdue Return Order" msgstr "逾期退貨訂單" -#: order/tasks.py:189 +#: order/tasks.py:190 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "退貨訂單 {ro} 已逾期" -#: part/api.py:103 +#: part/api.py:88 msgid "Starred" msgstr "已加星標" -#: part/api.py:105 +#: part/api.py:90 msgid "Filter by starred categories" msgstr "按星標類別篩選" -#: part/api.py:122 stock/api.py:288 +#: part/api.py:107 stock/api.py:287 msgid "Depth" msgstr "深度" -#: part/api.py:122 +#: part/api.py:107 msgid "Filter by category depth" msgstr "按類別深度篩選" -#: part/api.py:140 stock/api.py:306 +#: part/api.py:125 stock/api.py:305 msgid "Top Level" msgstr "頂級" -#: part/api.py:142 +#: part/api.py:127 msgid "Filter by top-level categories" msgstr "按頂級類別篩選" -#: part/api.py:155 stock/api.py:321 +#: part/api.py:140 stock/api.py:320 msgid "Cascade" msgstr "級聯" -#: part/api.py:157 +#: part/api.py:142 msgid "Include sub-categories in filtered results" msgstr "在篩選結果中包含子類別" -#: part/api.py:177 +#: part/api.py:162 msgid "Parent" msgstr "父類" -#: part/api.py:179 +#: part/api.py:164 msgid "Filter by parent category" msgstr "按父類別篩選" -#: part/api.py:214 +#: part/api.py:199 msgid "Exclude sub-categories under the specified category" msgstr "排除指定類別下的子類別" -#: part/api.py:440 +#: part/api.py:424 msgid "Has Results" msgstr "有結果" -#: part/api.py:661 +#: part/api.py:654 msgid "Is Variant" msgstr "為變體" -#: part/api.py:669 +#: part/api.py:662 msgid "Is Revision" msgstr "是修訂版本" -#: part/api.py:679 +#: part/api.py:672 msgid "Has Revisions" msgstr "有修訂版本" -#: part/api.py:860 +#: part/api.py:870 msgid "BOM Valid" msgstr "物料清單合規" -#: part/api.py:969 +#: part/api.py:979 msgid "Cascade Categories" -msgstr "" +msgstr "級聯類別" -#: part/api.py:970 +#: part/api.py:980 msgid "If true, include items in child categories of the given category" -msgstr "" +msgstr "若為 true,則包含給定類別的子類別中的項目" -#: part/api.py:976 +#: part/api.py:986 msgid "Filter by numeric category ID or the literal 'null'" -msgstr "" +msgstr "依數字類別 ID 或常值 'null' 篩選" -#: part/api.py:1308 +#: part/api.py:1299 msgid "Assembly part is active" -msgstr "" +msgstr "組件零件處於作用中狀態" -#: part/api.py:1312 +#: part/api.py:1303 msgid "Assembly part is trackable" -msgstr "" +msgstr "組件零件可追蹤" -#: part/api.py:1316 +#: part/api.py:1307 msgid "Assembly part is testable" msgstr "裝配部份是可測試的" -#: part/api.py:1321 +#: part/api.py:1311 +msgid "Assembly part is locked" +msgstr "" + +#: part/api.py:1316 msgid "Component part is active" -msgstr "" +msgstr "子零件處於作用中狀態" -#: part/api.py:1325 +#: part/api.py:1320 msgid "Component part is trackable" -msgstr "" +msgstr "子零件可追蹤" -#: part/api.py:1329 +#: part/api.py:1324 msgid "Component part is testable" msgstr "組件部份是可測試的" -#: part/api.py:1333 +#: part/api.py:1328 msgid "Component part is an assembly" -msgstr "" +msgstr "子零件是一個組件" -#: part/api.py:1337 +#: part/api.py:1332 msgid "Component part is virtual" -msgstr "" +msgstr "子零件是虛擬的" -#: part/api.py:1341 +#: part/api.py:1336 msgid "Has available stock" -msgstr "" +msgstr "有可用庫存" -#: part/api.py:1398 +#: part/api.py:1393 msgid "Uses" msgstr "使用" @@ -5746,11 +5894,11 @@ msgstr "使用" msgid "Part Category" msgstr "零件類別" -#: part/models.py:93 users/ruleset.py:27 +#: part/models.py:93 users/ruleset.py:28 msgid "Part Categories" msgstr "零件類別" -#: part/models.py:111 part/models.py:1193 +#: part/models.py:111 part/models.py:1188 msgid "Default Location" msgstr "默認位置" @@ -5778,7 +5926,7 @@ msgstr "此類別零件的默認關鍵字" msgid "Icon" msgstr "圖標" -#: part/models.py:137 part/serializers.py:148 part/serializers.py:167 +#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 #: stock/models.py:187 msgid "Icon (optional)" msgstr "圖標(可選)" @@ -5799,1025 +5947,1050 @@ msgstr "默認值" msgid "Default Parameter Value" msgstr "默認參數值" -#: part/models.py:528 part/serializers.py:119 users/ruleset.py:28 +#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 msgid "Parts" msgstr "零件" -#: part/models.py:574 +#: part/models.py:575 msgid "Cannot delete parameters of a locked part" -msgstr "" +msgstr "無法刪除已鎖定零件的參數" -#: part/models.py:579 +#: part/models.py:580 msgid "Cannot modify parameters of a locked part" -msgstr "" +msgstr "無法修改已鎖定零件的參數" -#: part/models.py:590 +#: part/models.py:591 msgid "Cannot delete this part as it is locked" msgstr "無法刪除這個零件,因為它已被鎖定" -#: part/models.py:593 +#: part/models.py:594 msgid "Cannot delete this part as it is still active" msgstr "無法刪除這個零件,因為它仍然處於活動狀態" -#: part/models.py:598 +#: part/models.py:599 msgid "Cannot delete this part as it is used in an assembly" msgstr "無法刪除這個零件,因為它被使用在了裝配中" -#: part/models.py:682 part/models.py:689 +#: part/models.py:683 part/models.py:690 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "零件 \"{self}\" 不能用在 \"{parent}\" 的物料清單 (遞歸)" -#: part/models.py:701 +#: part/models.py:702 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "零件 \"{parent}\" 被使用在了 \"{self}\" 的物料清單 (遞歸)" -#: part/models.py:768 +#: part/models.py:769 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "內部零件號必須匹配正則表達式 {pattern}" -#: part/models.py:776 +#: part/models.py:777 msgid "Part cannot be a revision of itself" msgstr "零件不能是對自身的修訂" -#: part/models.py:783 -msgid "Cannot make a revision of a part which is already a revision" -msgstr "無法對已經是修訂版本的零件進行修訂" +#: part/models.py:784 +msgid "Revision code must be specified for a part marked as a revision" +msgstr "標記為修訂版的零件必須指定修訂版代碼" -#: part/models.py:790 -msgid "Revision code must be specified" -msgstr "必須指定修訂代碼" - -#: part/models.py:797 +#: part/models.py:792 msgid "Revisions are only allowed for assembly parts" msgstr "修訂僅對裝配零件允許" -#: part/models.py:804 +#: part/models.py:799 msgid "Cannot make a revision of a template part" msgstr "無法對模版零件進行修訂" -#: part/models.py:810 +#: part/models.py:805 msgid "Parent part must point to the same template" msgstr "上級零件必須指向相同的模版" -#: part/models.py:907 +#: part/models.py:902 msgid "Stock item with this serial number already exists" msgstr "該序列號庫存項己存在" -#: part/models.py:1037 +#: part/models.py:1032 msgid "Duplicate IPN not allowed in part settings" msgstr "在零件設置中不允許重複的內部零件號" -#: part/models.py:1050 +#: part/models.py:1045 msgid "Duplicate part revision already exists." msgstr "重複的零件修訂版本已經存在。" -#: part/models.py:1060 +#: part/models.py:1055 msgid "Part with this Name, IPN and Revision already exists." msgstr "有這個名字,內部零件號,和修訂版本的零件已經存在" -#: part/models.py:1075 +#: part/models.py:1070 msgid "Parts cannot be assigned to structural part categories!" msgstr "零件不能分配到結構性零件類別!" -#: part/models.py:1107 +#: part/models.py:1102 msgid "Part name" msgstr "零件名稱" -#: part/models.py:1112 +#: part/models.py:1107 msgid "Is Template" msgstr "是模板" -#: part/models.py:1113 +#: part/models.py:1108 msgid "Is this part a template part?" msgstr "這個零件是一個模版零件嗎?" -#: part/models.py:1123 +#: part/models.py:1118 msgid "Is this part a variant of another part?" msgstr "這個零件是另一零件的變體嗎?" -#: part/models.py:1124 +#: part/models.py:1119 msgid "Variant Of" msgstr "變體" -#: part/models.py:1131 +#: part/models.py:1126 msgid "Part description (optional)" msgstr "零件描述(可選)" -#: part/models.py:1138 +#: part/models.py:1133 msgid "Keywords" msgstr "關鍵詞" -#: part/models.py:1139 +#: part/models.py:1134 msgid "Part keywords to improve visibility in search results" msgstr "提高搜索結果可見性的零件關鍵字" -#: part/models.py:1149 +#: part/models.py:1144 msgid "Part category" msgstr "零件類別" -#: part/models.py:1156 part/serializers.py:801 +#: part/models.py:1151 part/serializers.py:828 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "內部零件號 IPN" -#: part/models.py:1164 +#: part/models.py:1159 msgid "Part revision or version number" msgstr "零件修訂版本或版本號" -#: part/models.py:1165 report/models.py:228 +#: part/models.py:1160 report/models.py:231 msgid "Revision" msgstr "版本" -#: part/models.py:1174 +#: part/models.py:1169 msgid "Is this part a revision of another part?" msgstr "這零件是另一零件的修訂版本嗎?" -#: part/models.py:1175 +#: part/models.py:1170 msgid "Revision Of" msgstr "修訂版本" -#: part/models.py:1191 +#: part/models.py:1186 msgid "Where is this item normally stored?" msgstr "該物品通常存放在哪裏?" -#: part/models.py:1228 +#: part/models.py:1223 msgid "Default Expiry" msgstr "默認到期" -#: part/models.py:1229 +#: part/models.py:1224 msgid "Expiry time (in days) for stock items of this part" msgstr "此零件庫存項的過期時間 (天)" -#: part/models.py:1237 part/serializers.py:871 +#: part/models.py:1232 part/serializers.py:898 msgid "Minimum Stock" msgstr "最低庫存" -#: part/models.py:1238 +#: part/models.py:1233 msgid "Minimum allowed stock level" msgstr "允許的最小庫存量" -#: part/models.py:1247 +#: part/models.py:1241 part/serializers.py:902 +msgid "Maximum Stock" +msgstr "" + +#: part/models.py:1242 +msgid "Maximum allowed stock level" +msgstr "" + +#: part/models.py:1251 msgid "Units of measure for this part" msgstr "此零件的計量單位" -#: part/models.py:1254 +#: part/models.py:1258 msgid "Can this part be built from other parts?" msgstr "這個零件可由其他零件加工而成嗎?" -#: part/models.py:1260 +#: part/models.py:1264 msgid "Can this part be used to build other parts?" msgstr "這個零件可用於創建其他零件嗎?" -#: part/models.py:1266 +#: part/models.py:1270 msgid "Does this part have tracking for unique items?" msgstr "此零件是否有唯一物品的追蹤功能" -#: part/models.py:1272 +#: part/models.py:1276 msgid "Can this part have test results recorded against it?" msgstr "這一部分能否記錄到測試結果?" -#: part/models.py:1278 +#: part/models.py:1282 msgid "Can this part be purchased from external suppliers?" msgstr "這個零件可從外部供應商購買嗎?" -#: part/models.py:1284 +#: part/models.py:1288 msgid "Can this part be sold to customers?" msgstr "此零件可以銷售給客户嗎?" -#: part/models.py:1288 +#: part/models.py:1292 msgid "Is this part active?" msgstr "這個零件是否已激活?" -#: part/models.py:1294 +#: part/models.py:1298 msgid "Locked parts cannot be edited" msgstr "無法編輯鎖定的零件" -#: part/models.py:1300 +#: part/models.py:1304 msgid "Is this a virtual part, such as a software product or license?" msgstr "這是一個虛擬零件,例如一個軟件產品或許可證嗎?" -#: part/models.py:1305 +#: part/models.py:1309 msgid "BOM Validated" msgstr "BOM 已驗證" -#: part/models.py:1306 +#: part/models.py:1310 msgid "Is the BOM for this part valid?" msgstr "此零件的 BOM 是否已通過驗證?" -#: part/models.py:1312 +#: part/models.py:1316 msgid "BOM checksum" msgstr "物料清單校驗和" -#: part/models.py:1313 +#: part/models.py:1317 msgid "Stored BOM checksum" msgstr "保存的物料清單校驗和" -#: part/models.py:1321 +#: part/models.py:1325 msgid "BOM checked by" msgstr "物料清單檢查人" -#: part/models.py:1326 +#: part/models.py:1330 msgid "BOM checked date" msgstr "物料清單檢查日期" -#: part/models.py:1342 +#: part/models.py:1346 msgid "Creation User" msgstr "新建用户" -#: part/models.py:1352 +#: part/models.py:1356 msgid "Owner responsible for this part" msgstr "此零件的負責人" -#: part/models.py:2309 +#: part/models.py:2318 msgid "Sell multiple" msgstr "出售多個" -#: part/models.py:3313 +#: part/models.py:3327 msgid "Currency used to cache pricing calculations" msgstr "用於緩存定價計算的貨幣" -#: part/models.py:3329 +#: part/models.py:3343 msgid "Minimum BOM Cost" msgstr "最低物料清單成本" -#: part/models.py:3330 +#: part/models.py:3344 msgid "Minimum cost of component parts" msgstr "元件的最低成本" -#: part/models.py:3336 +#: part/models.py:3350 msgid "Maximum BOM Cost" msgstr "物料清單的最高成本" -#: part/models.py:3337 +#: part/models.py:3351 msgid "Maximum cost of component parts" msgstr "元件的最高成本" -#: part/models.py:3343 +#: part/models.py:3357 msgid "Minimum Purchase Cost" msgstr "最低購買成本" -#: part/models.py:3344 +#: part/models.py:3358 msgid "Minimum historical purchase cost" msgstr "最高歷史購買成本" -#: part/models.py:3350 +#: part/models.py:3364 msgid "Maximum Purchase Cost" msgstr "最大購買成本" -#: part/models.py:3351 +#: part/models.py:3365 msgid "Maximum historical purchase cost" msgstr "最高歷史購買成本" -#: part/models.py:3357 +#: part/models.py:3371 msgid "Minimum Internal Price" msgstr "最低內部價格" -#: part/models.py:3358 +#: part/models.py:3372 msgid "Minimum cost based on internal price breaks" msgstr "基於內部批發價的最低成本" -#: part/models.py:3364 +#: part/models.py:3378 msgid "Maximum Internal Price" msgstr "最大內部價格" -#: part/models.py:3365 +#: part/models.py:3379 msgid "Maximum cost based on internal price breaks" msgstr "基於內部批發價的最高成本" -#: part/models.py:3371 +#: part/models.py:3385 msgid "Minimum Supplier Price" msgstr "供應商最低價格" -#: part/models.py:3372 +#: part/models.py:3386 msgid "Minimum price of part from external suppliers" msgstr "外部供應商零件的最低價格" -#: part/models.py:3378 +#: part/models.py:3392 msgid "Maximum Supplier Price" msgstr "供應商最高價格" -#: part/models.py:3379 +#: part/models.py:3393 msgid "Maximum price of part from external suppliers" msgstr "來自外部供應商的商零件的最高價格" -#: part/models.py:3385 +#: part/models.py:3399 msgid "Minimum Variant Cost" msgstr "最小變體成本" -#: part/models.py:3386 +#: part/models.py:3400 msgid "Calculated minimum cost of variant parts" msgstr "計算出的變體零件的最低成本" -#: part/models.py:3392 +#: part/models.py:3406 msgid "Maximum Variant Cost" msgstr "最大變體成本" -#: part/models.py:3393 +#: part/models.py:3407 msgid "Calculated maximum cost of variant parts" msgstr "計算出的變體零件的最大成本" -#: part/models.py:3399 part/models.py:3413 +#: part/models.py:3413 part/models.py:3427 msgid "Minimum Cost" msgstr "最低成本" -#: part/models.py:3400 +#: part/models.py:3414 msgid "Override minimum cost" msgstr "覆蓋最低成本" -#: part/models.py:3406 part/models.py:3420 +#: part/models.py:3420 part/models.py:3434 msgid "Maximum Cost" msgstr "最高成本" -#: part/models.py:3407 +#: part/models.py:3421 msgid "Override maximum cost" msgstr "覆蓋最大成本" -#: part/models.py:3414 +#: part/models.py:3428 msgid "Calculated overall minimum cost" msgstr "計算總最低成本" -#: part/models.py:3421 +#: part/models.py:3435 msgid "Calculated overall maximum cost" msgstr "計算總最大成本" -#: part/models.py:3427 +#: part/models.py:3441 msgid "Minimum Sale Price" msgstr "最低售出價格" -#: part/models.py:3428 +#: part/models.py:3442 msgid "Minimum sale price based on price breaks" msgstr "基於批發價的最低售出價格" -#: part/models.py:3434 +#: part/models.py:3448 msgid "Maximum Sale Price" msgstr "最高售出價格" -#: part/models.py:3435 +#: part/models.py:3449 msgid "Maximum sale price based on price breaks" msgstr "基於批發價的最大售出價格" -#: part/models.py:3441 +#: part/models.py:3455 msgid "Minimum Sale Cost" msgstr "最低銷售成本" -#: part/models.py:3442 +#: part/models.py:3456 msgid "Minimum historical sale price" msgstr "歷史最低售出價格" -#: part/models.py:3448 +#: part/models.py:3462 msgid "Maximum Sale Cost" msgstr "最高銷售成本" -#: part/models.py:3449 +#: part/models.py:3463 msgid "Maximum historical sale price" msgstr "歷史最高售出價格" -#: part/models.py:3467 +#: part/models.py:3481 msgid "Part for stocktake" msgstr "用於盤點的零件" -#: part/models.py:3472 +#: part/models.py:3486 msgid "Item Count" msgstr "物品數量" -#: part/models.py:3473 +#: part/models.py:3487 msgid "Number of individual stock entries at time of stocktake" msgstr "盤點時的個別庫存條目數" -#: part/models.py:3481 +#: part/models.py:3495 msgid "Total available stock at time of stocktake" msgstr "盤點時可用庫存總額" -#: part/models.py:3485 report/templates/report/inventree_test_report.html:106 +#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3129 msgid "Date" msgstr "日期" -#: part/models.py:3486 +#: part/models.py:3500 msgid "Date stocktake was performed" msgstr "進行盤點的日期" -#: part/models.py:3493 +#: part/models.py:3507 msgid "Minimum Stock Cost" msgstr "最低庫存成本" -#: part/models.py:3494 +#: part/models.py:3508 msgid "Estimated minimum cost of stock on hand" msgstr "現有存庫存最低成本估算" -#: part/models.py:3500 +#: part/models.py:3514 msgid "Maximum Stock Cost" msgstr "最高庫存成本" -#: part/models.py:3501 +#: part/models.py:3515 msgid "Estimated maximum cost of stock on hand" msgstr "目前庫存最高成本估算" -#: part/models.py:3511 +#: part/models.py:3525 msgid "Part Sale Price Break" msgstr "零件售出價格折扣" -#: part/models.py:3625 +#: part/models.py:3639 msgid "Part Test Template" msgstr "零件測試模板" -#: part/models.py:3651 +#: part/models.py:3665 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "模板名稱無效 - 必須包含至少一個字母或者數字" -#: part/models.py:3683 +#: part/models.py:3697 msgid "Test templates can only be created for testable parts" msgstr "測試模板只能為可拆分的部件創建" -#: part/models.py:3697 +#: part/models.py:3711 msgid "Test template with the same key already exists for part" msgstr "零件已存在具有相同主鍵的測試模板" -#: part/models.py:3714 +#: part/models.py:3728 msgid "Test Name" msgstr "測試名" -#: part/models.py:3715 +#: part/models.py:3729 msgid "Enter a name for the test" msgstr "輸入測試的名稱" -#: part/models.py:3721 +#: part/models.py:3735 msgid "Test Key" msgstr "測試主鍵" -#: part/models.py:3722 +#: part/models.py:3736 msgid "Simplified key for the test" msgstr "簡化測試主鍵" -#: part/models.py:3729 +#: part/models.py:3743 msgid "Test Description" msgstr "測試説明" -#: part/models.py:3730 +#: part/models.py:3744 msgid "Enter description for this test" msgstr "輸入測試的描述" -#: part/models.py:3734 +#: part/models.py:3748 msgid "Is this test enabled?" msgstr "此測試是否已啓用?" -#: part/models.py:3739 +#: part/models.py:3753 msgid "Required" msgstr "必須的" -#: part/models.py:3740 +#: part/models.py:3754 msgid "Is this test required to pass?" msgstr "需要此測試才能通過嗎?" -#: part/models.py:3745 +#: part/models.py:3759 msgid "Requires Value" msgstr "需要值" -#: part/models.py:3746 +#: part/models.py:3760 msgid "Does this test require a value when adding a test result?" msgstr "添加測試結果時是否需要一個值?" -#: part/models.py:3751 +#: part/models.py:3765 msgid "Requires Attachment" msgstr "需要附件" -#: part/models.py:3753 +#: part/models.py:3767 msgid "Does this test require a file attachment when adding a test result?" msgstr "添加測試結果時是否需要文件附件?" -#: part/models.py:3760 +#: part/models.py:3774 msgid "Valid choices for this test (comma-separated)" msgstr "此測試的有效選擇 (逗號分隔)" -#: part/models.py:3954 +#: part/models.py:3918 +msgid "Invalid quantity - no units specified for part" +msgstr "" + +#: part/models.py:3927 +msgid "Quantity must be greater than or equal to zero" +msgstr "數量必須大於或等於零" + +#: part/models.py:4023 msgid "BOM item cannot be modified - assembly is locked" msgstr "物料清單項目不能被修改 - 裝配已鎖定" -#: part/models.py:3961 +#: part/models.py:4030 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "物料清單項目不能修改 - 變體裝配已鎖定" -#: part/models.py:3971 +#: part/models.py:4040 msgid "Select parent part" msgstr "選擇父零件" -#: part/models.py:3981 +#: part/models.py:4050 msgid "Sub part" msgstr "子零件" -#: part/models.py:3982 +#: part/models.py:4051 msgid "Select part to be used in BOM" msgstr "選擇要用於物料清單的零件" -#: part/models.py:3993 +#: part/models.py:4057 part/serializers.py:1688 +msgid "Amount" +msgstr "" + +#: part/models.py:4058 +msgid "Amount of sub-part consumed to produce one part" +msgstr "" + +#: part/models.py:4070 msgid "BOM quantity for this BOM item" msgstr "此物料清單項目的數量" -#: part/models.py:3999 +#: part/models.py:4076 msgid "This BOM item is optional" msgstr "此物料清單項目是可選的" -#: part/models.py:4005 +#: part/models.py:4082 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "這個物料清單項目是耗材 (它沒有在生產訂單中被追蹤)" -#: part/models.py:4013 +#: part/models.py:4090 msgid "Setup Quantity" msgstr "建置額外數量" -#: part/models.py:4014 +#: part/models.py:4091 msgid "Extra required quantity for a build, to account for setup losses" msgstr "為彌補建置 / 開工損耗所需的額外數量" -#: part/models.py:4022 +#: part/models.py:4099 msgid "Attrition" msgstr "損耗率" -#: part/models.py:4024 +#: part/models.py:4101 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "製造預估損耗(百分比 0–100)" -#: part/models.py:4035 +#: part/models.py:4112 msgid "Rounding Multiple" msgstr "進位倍數" -#: part/models.py:4037 +#: part/models.py:4114 msgid "Round up required production quantity to nearest multiple of this value" msgstr "將所需生產數量向上取整到此數值的整數倍" -#: part/models.py:4045 +#: part/models.py:4122 msgid "BOM item reference" msgstr "物料清單項目引用" -#: part/models.py:4053 +#: part/models.py:4130 msgid "BOM item notes" msgstr "物料清單項目註釋" -#: part/models.py:4059 +#: part/models.py:4136 msgid "Checksum" msgstr "校驗和" -#: part/models.py:4060 +#: part/models.py:4137 msgid "BOM line checksum" msgstr "物料清單行校驗和" -#: part/models.py:4065 +#: part/models.py:4142 msgid "Validated" msgstr "已驗證" -#: part/models.py:4066 +#: part/models.py:4143 msgid "This BOM item has been validated" msgstr "此物料清單項目已驗證" -#: part/models.py:4071 +#: part/models.py:4148 msgid "Gets inherited" msgstr "獲取繼承的" -#: part/models.py:4072 +#: part/models.py:4149 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "此物料清單項目是由物料清單繼承的變體零件" -#: part/models.py:4078 +#: part/models.py:4155 msgid "Stock items for variant parts can be used for this BOM item" msgstr "變體零件的庫存項可以用於此物料清單項目" -#: part/models.py:4185 stock/models.py:930 +#: part/models.py:4262 stock/models.py:956 msgid "Quantity must be integer value for trackable parts" msgstr "可追蹤零件的數量必須是整數" -#: part/models.py:4195 part/models.py:4197 +#: part/models.py:4272 part/models.py:4274 msgid "Sub part must be specified" msgstr "必須指定子零件" -#: part/models.py:4348 +#: part/models.py:4425 msgid "BOM Item Substitute" msgstr "物料清單項目替代品" -#: part/models.py:4369 +#: part/models.py:4446 msgid "Substitute part cannot be the same as the master part" msgstr "替代品零件不能與主零件相同" -#: part/models.py:4382 +#: part/models.py:4459 msgid "Parent BOM item" msgstr "上級物料清單項目" -#: part/models.py:4390 +#: part/models.py:4467 msgid "Substitute part" msgstr "替代品零件" -#: part/models.py:4406 +#: part/models.py:4483 msgid "Part 1" msgstr "零件 1" -#: part/models.py:4414 +#: part/models.py:4491 msgid "Part 2" msgstr "零件2" -#: part/models.py:4415 +#: part/models.py:4492 msgid "Select Related Part" msgstr "選擇相關的零件" -#: part/models.py:4422 +#: part/models.py:4499 msgid "Note for this relationship" msgstr "此關係的備註" -#: part/models.py:4441 +#: part/models.py:4518 msgid "Part relationship cannot be created between a part and itself" msgstr "零件關係不能在零件和自身之間創建" -#: part/models.py:4446 +#: part/models.py:4523 msgid "Duplicate relationship already exists" msgstr "複製關係已經存在" -#: part/serializers.py:114 +#: part/serializers.py:107 msgid "Parent Category" msgstr "上級類別" -#: part/serializers.py:115 +#: part/serializers.py:108 msgid "Parent part category" msgstr "上級零件類別" -#: part/serializers.py:123 part/serializers.py:164 +#: part/serializers.py:116 part/serializers.py:168 msgid "Subcategories" msgstr "子類別" -#: part/serializers.py:203 +#: part/serializers.py:207 msgid "Results" msgstr "結果" -#: part/serializers.py:204 +#: part/serializers.py:208 msgid "Number of results recorded against this template" msgstr "根據該模板記錄的結果數量" -#: part/serializers.py:235 part/serializers.py:253 stock/serializers.py:647 +#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 msgid "Purchase currency of this stock item" msgstr "購買此庫存項的貨幣" -#: part/serializers.py:280 +#: part/serializers.py:284 msgid "File is not an image" msgstr "檔案不是圖片" -#: part/serializers.py:383 +#: part/serializers.py:394 msgid "Original Part" msgstr "原始零件" -#: part/serializers.py:384 +#: part/serializers.py:395 msgid "Select original part to duplicate" msgstr "選擇要複製的原始零件" -#: part/serializers.py:389 +#: part/serializers.py:400 msgid "Copy Image" msgstr "複製圖片" -#: part/serializers.py:390 +#: part/serializers.py:401 msgid "Copy image from original part" msgstr "從原零件複製圖片" -#: part/serializers.py:396 +#: part/serializers.py:407 msgid "Copy BOM" msgstr "複製物料清單" -#: part/serializers.py:397 +#: part/serializers.py:408 msgid "Copy bill of materials from original part" msgstr "從原始零件複製材料清單" -#: part/serializers.py:403 -msgid "Copy Parameters" -msgstr "複製參數" - -#: part/serializers.py:404 +#: part/serializers.py:415 msgid "Copy parameter data from original part" msgstr "從原始零件複製參數數據" -#: part/serializers.py:410 +#: part/serializers.py:421 msgid "Copy Notes" msgstr "複製備註" -#: part/serializers.py:411 +#: part/serializers.py:422 msgid "Copy notes from original part" msgstr "從原始零件複製備註" -#: part/serializers.py:417 +#: part/serializers.py:428 msgid "Copy Tests" msgstr "複製測試模板" -#: part/serializers.py:418 +#: part/serializers.py:429 msgid "Copy test templates from original part" msgstr "從原始零件複製測試模板" -#: part/serializers.py:436 +#: part/serializers.py:447 msgid "Initial Stock Quantity" msgstr "初始化庫存數量" -#: part/serializers.py:438 +#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "指定此零件的初始庫存數量。如果數量為零,則不添加任何庫存。" -#: part/serializers.py:445 +#: part/serializers.py:456 msgid "Initial Stock Location" msgstr "初始化庫存地點" -#: part/serializers.py:446 +#: part/serializers.py:457 msgid "Specify initial stock location for this Part" msgstr "初始化指定此零件的庫存地點" -#: part/serializers.py:463 +#: part/serializers.py:474 msgid "Select supplier (or leave blank to skip)" msgstr "選擇供應商(或為空以跳過)" -#: part/serializers.py:479 +#: part/serializers.py:490 msgid "Select manufacturer (or leave blank to skip)" msgstr "選擇製造商(或為空)" -#: part/serializers.py:489 +#: part/serializers.py:500 msgid "Manufacturer part number" msgstr "製造商零件號" -#: part/serializers.py:496 +#: part/serializers.py:507 msgid "Selected company is not a valid supplier" msgstr "所選公司不是一個有效的供應商" -#: part/serializers.py:505 +#: part/serializers.py:516 msgid "Selected company is not a valid manufacturer" msgstr "所選公司不是一個有效的製造商" -#: part/serializers.py:516 +#: part/serializers.py:527 msgid "Manufacturer part matching this MPN already exists" msgstr "與此製造商零件編號 (MPN) 的相匹配的製造商零件已存在" -#: part/serializers.py:523 +#: part/serializers.py:534 msgid "Supplier part matching this SKU already exists" msgstr "匹配此庫存單位 (SKU) 的供應商零件已存在" -#: part/serializers.py:786 +#: part/serializers.py:813 msgid "Category Name" msgstr "類別名稱" -#: part/serializers.py:815 +#: part/serializers.py:842 msgid "Building" msgstr "正在生產" -#: part/serializers.py:816 +#: part/serializers.py:843 msgid "Quantity of this part currently being in production" msgstr "此零件目前生產中數量" -#: part/serializers.py:823 +#: part/serializers.py:850 msgid "Outstanding quantity of this part scheduled to be built" msgstr "此零件排程待製造未完成數量" -#: part/serializers.py:843 stock/serializers.py:1023 stock/serializers.py:1206 -#: users/ruleset.py:30 +#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 +#: users/ruleset.py:32 msgid "Stock Items" msgstr "庫存項" -#: part/serializers.py:847 +#: part/serializers.py:874 msgid "Revisions" msgstr "修訂" -#: part/serializers.py:851 part/serializers.py:1143 +#: part/serializers.py:878 part/serializers.py:1177 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "庫存總量" -#: part/serializers.py:859 +#: part/serializers.py:886 msgid "Unallocated Stock" msgstr "未分配的庫存" -#: part/serializers.py:867 +#: part/serializers.py:894 msgid "Variant Stock" msgstr "變體庫存" -#: part/serializers.py:923 +#: part/serializers.py:969 msgid "Duplicate Part" msgstr "重複零件" -#: part/serializers.py:924 +#: part/serializers.py:970 msgid "Copy initial data from another Part" msgstr "從另一個零件複製初始數據" -#: part/serializers.py:930 +#: part/serializers.py:976 msgid "Initial Stock" msgstr "初始庫存" -#: part/serializers.py:931 +#: part/serializers.py:977 msgid "Create Part with initial stock quantity" msgstr "創建具有初始庫存數量的零件" -#: part/serializers.py:937 +#: part/serializers.py:983 msgid "Supplier Information" msgstr "供應商信息" -#: part/serializers.py:938 +#: part/serializers.py:984 msgid "Add initial supplier information for this part" msgstr "添加此零件的初始供應商信息" -#: part/serializers.py:947 +#: part/serializers.py:993 msgid "Copy Category Parameters" msgstr "複製類別參數" -#: part/serializers.py:948 +#: part/serializers.py:994 msgid "Copy parameter templates from selected part category" msgstr "從選擇的零件複製參數模版" -#: part/serializers.py:953 +#: part/serializers.py:999 msgid "Existing Image" msgstr "現有的圖片" -#: part/serializers.py:954 +#: part/serializers.py:1000 msgid "Filename of an existing part image" msgstr "現有零件圖片的文件名" -#: part/serializers.py:971 +#: part/serializers.py:1017 msgid "Image file does not exist" msgstr "圖片不存在" -#: part/serializers.py:1115 +#: part/serializers.py:1149 msgid "Validate entire Bill of Materials" msgstr "驗證整個物料清單" -#: part/serializers.py:1149 part/serializers.py:1729 +#: part/serializers.py:1183 part/serializers.py:1779 msgid "Can Build" msgstr "可以創建" -#: part/serializers.py:1166 +#: part/serializers.py:1200 msgid "Required for Build Orders" msgstr "生產工單需求數" -#: part/serializers.py:1171 +#: part/serializers.py:1205 msgid "Allocated to Build Orders" msgstr "已分配至生產工單" -#: part/serializers.py:1178 +#: part/serializers.py:1212 msgid "Required for Sales Orders" msgstr "銷售訂單需求數" -#: part/serializers.py:1182 +#: part/serializers.py:1216 msgid "Allocated to Sales Orders" msgstr "已分配至銷售訂單" -#: part/serializers.py:1242 +#: part/serializers.py:1276 msgid "Part IPN" -msgstr "" +msgstr "零件 IPN" -#: part/serializers.py:1249 +#: part/serializers.py:1283 msgid "Part Description" -msgstr "" +msgstr "零件描述" -#: part/serializers.py:1288 +#: part/serializers.py:1327 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "選擇一個零件以產生該零件 (及其任何變體零件) 的盤點資訊" -#: part/serializers.py:1298 +#: part/serializers.py:1337 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "選擇一個類別以包含該類別 (及其子類別) 內的所有零件" -#: part/serializers.py:1308 +#: part/serializers.py:1347 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "選擇一個位置以包含該位置 (及其子位置) 內所有有庫存的零件" -#: part/serializers.py:1315 +#: part/serializers.py:1354 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "產生盤點項目" -#: part/serializers.py:1316 +#: part/serializers.py:1355 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "儲存選定零件的盤點項目" -#: part/serializers.py:1323 +#: part/serializers.py:1362 msgid "Generate Report" -msgstr "" +msgstr "產製報表" -#: part/serializers.py:1324 +#: part/serializers.py:1363 msgid "Generate a stocktake report for the selected parts" -msgstr "" +msgstr "產製選定零件的庫存報表" -#: part/serializers.py:1427 +#: part/serializers.py:1466 msgid "Minimum Price" msgstr "最低價格" -#: part/serializers.py:1428 +#: part/serializers.py:1467 msgid "Override calculated value for minimum price" msgstr "覆蓋已計算的最低價格值" -#: part/serializers.py:1435 +#: part/serializers.py:1474 msgid "Minimum price currency" msgstr "最低價格貨幣" -#: part/serializers.py:1442 +#: part/serializers.py:1481 msgid "Maximum Price" msgstr "最高價格" -#: part/serializers.py:1443 +#: part/serializers.py:1482 msgid "Override calculated value for maximum price" msgstr "覆蓋已計算的最高價格值" -#: part/serializers.py:1450 +#: part/serializers.py:1489 msgid "Maximum price currency" msgstr "最高價格貨幣" -#: part/serializers.py:1479 +#: part/serializers.py:1518 msgid "Update" msgstr "更新" -#: part/serializers.py:1480 +#: part/serializers.py:1519 msgid "Update pricing for this part" msgstr "更新這個零件的價格" -#: part/serializers.py:1503 +#: part/serializers.py:1542 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "無法將所提供的貨幣轉換為 {default_currency}" -#: part/serializers.py:1510 +#: part/serializers.py:1549 msgid "Minimum price must not be greater than maximum price" msgstr "最低價格不能高於最高價格。" -#: part/serializers.py:1513 +#: part/serializers.py:1552 msgid "Maximum price must not be less than minimum price" msgstr "最高價格不能低於最低價格" -#: part/serializers.py:1667 +#: part/serializers.py:1689 +msgid "Amount required for this item (can include units)" +msgstr "" + +#: part/serializers.py:1706 msgid "Select the parent assembly" msgstr "選擇父裝配" -#: part/serializers.py:1695 +#: part/serializers.py:1741 msgid "Select the component part" msgstr "選擇零部件" -#: part/serializers.py:1897 +#: part/serializers.py:1861 +msgid "Invalid quantity format" +msgstr "" + +#: part/serializers.py:1989 msgid "Select part to copy BOM from" msgstr "選擇要複製物料清單的零件" -#: part/serializers.py:1905 +#: part/serializers.py:1997 msgid "Remove Existing Data" msgstr "移除現有數據" -#: part/serializers.py:1906 +#: part/serializers.py:1998 msgid "Remove existing BOM items before copying" msgstr "複製前刪除現有的物料清單項目" -#: part/serializers.py:1911 +#: part/serializers.py:2003 msgid "Include Inherited" msgstr "包含繼承的" -#: part/serializers.py:1912 +#: part/serializers.py:2004 msgid "Include BOM items which are inherited from templated parts" msgstr "包含從模板零件繼承的物料清單項目" -#: part/serializers.py:1917 +#: part/serializers.py:2009 msgid "Skip Invalid Rows" msgstr "跳過無效行" -#: part/serializers.py:1918 +#: part/serializers.py:2010 msgid "Enable this option to skip invalid rows" msgstr "啓用此選項以跳過無效行" -#: part/serializers.py:1923 +#: part/serializers.py:2015 msgid "Copy Substitute Parts" msgstr "複製替代品零件" -#: part/serializers.py:1924 +#: part/serializers.py:2016 msgid "Copy substitute parts when duplicate BOM items" msgstr "複製物料清單項目時複製替代品零件" -#: part/tasks.py:41 +#: part/tasks.py:42 msgid "Low stock notification" msgstr "低庫存通知" -#: part/tasks.py:43 +#: part/tasks.py:44 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "可用的 {part.name}庫存已經跌到設置的最低值" -#: part/tasks.py:73 +#: part/tasks.py:74 msgid "Stale stock notification" msgstr "庫存即將過期通知" -#: part/tasks.py:77 +#: part/tasks.py:78 msgid "You have 1 stock item approaching its expiry date" msgstr "有 1 個庫存項目即將到期" -#: part/tasks.py:79 +#: part/tasks.py:80 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "有 {item_count} 個庫存項目即將到期" -#: part/tasks.py:88 +#: part/tasks.py:89 msgid "No expiry date" msgstr "未設定到期日" -#: part/tasks.py:95 +#: part/tasks.py:96 msgid "Expired {abs(days_diff)} days ago" msgstr "已於 {abs(days_diff)} 天前到期" -#: part/tasks.py:98 +#: part/tasks.py:99 msgid "Expires today" msgstr "今日到期" -#: part/tasks.py:101 +#: part/tasks.py:102 #, python-brace-format msgid "{days_until_expiry} days" msgstr "尚餘 {days_until_expiry} 天" @@ -7031,15 +7204,15 @@ msgstr "待分配數" msgid "Label printing failed" msgstr "標籤打印失敗" -#: plugin/base/label/mixins.py:53 +#: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" msgstr "渲染標籤到 PDF 時出錯" -#: plugin/base/label/mixins.py:67 +#: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" msgstr "渲染標籤到 HTML 時出錯" -#: plugin/base/label/mixins.py:144 +#: plugin/base/label/mixins.py:156 msgid "No items provided to print" msgstr "沒有要打印的項目" @@ -7100,7 +7273,7 @@ msgstr "提供條形碼本地支持" #: 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:26 +#: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 #: plugin/builtin/labels/label_sheet.py:72 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 @@ -7307,19 +7480,19 @@ msgstr "支援自 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" @@ -7395,7 +7568,7 @@ msgstr "整合的 Slack 通知方式" #: plugin/builtin/integration/core_notifications.py:131 msgid "Slack incoming webhook URL" -msgstr "" +msgstr "Slack 傳入 Webhook URL" #: plugin/builtin/integration/core_notifications.py:132 msgid "URL that is used to send messages to a slack channel" @@ -7415,11 +7588,11 @@ 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 "InvenTree 內建機器類型" #: plugin/builtin/integration/part_notifications.py:20 msgid "Part Notifications" @@ -7446,20 +7619,20 @@ msgstr "零件變更通知" msgid "The part `{part.name}` has been triggered with a `{part_action}` event" msgstr "零件 `{part.name}` 觸發 `{part_action}` 事件" -#: plugin/builtin/labels/inventree_label.py:23 +#: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" msgstr "InvenTree PDF 標籤打印機" -#: plugin/builtin/labels/inventree_label.py:24 +#: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" msgstr "為打印 PDF 標籤提供本機支持" -#: plugin/builtin/labels/inventree_label.py:32 +#: plugin/builtin/labels/inventree_label.py:33 #: plugin/builtin/labels/label_sheet.py:78 msgid "Debug mode" msgstr "Debug模式" -#: plugin/builtin/labels/inventree_label.py:33 +#: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "啓用Debug模式 - 返回原始的 HTML 而不是 PDF" @@ -7500,7 +7673,7 @@ msgstr "邊框" msgid "Print a border around each label" msgstr "打印每個標籤的邊框" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:387 +#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 msgid "Landscape" msgstr "橫屏模式" @@ -7580,64 +7753,77 @@ msgstr "為掃描 TME 條形碼提供支持" msgid "The Supplier which acts as 'TME'" msgstr "作為‘TME’的供應商" -#: plugin/installer.py:240 plugin/installer.py:320 -msgid "Only staff users can administer plugins" -msgstr "只有員工用户可以管理插件" +#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "只有超級使用者帳號可以管理外掛程式" #: plugin/installer.py:243 msgid "Plugin installation is disabled" msgstr "插件安裝已禁用" -#: plugin/installer.py:280 +#: plugin/installer.py:273 +msgid "No package name or URL provided for installation" +msgstr "未提供要安裝的套件名稱或 URL" + +#: plugin/installer.py:277 +msgid "Invalid characters in package name or URL" +msgstr "套件名稱或 URL 中包含無效字元" + +#: plugin/installer.py:287 msgid "Installed plugin successfully" msgstr "插件安裝成功" -#: plugin/installer.py:285 +#: plugin/installer.py:292 #, python-brace-format msgid "Installed plugin into {path}" msgstr "插件安裝到 {path}" -#: plugin/installer.py:311 +#: plugin/installer.py:318 msgid "Plugin was not found in registry" msgstr "在插件倉庫中找不到插件" -#: plugin/installer.py:314 +#: plugin/installer.py:321 msgid "Plugin is not a packaged plugin" msgstr "插件不是一個打包的插件" -#: plugin/installer.py:317 +#: plugin/installer.py:324 msgid "Plugin package name not found" msgstr "找不到插件包名稱" -#: plugin/installer.py:337 +#: plugin/installer.py:327 +msgid "Only staff users can administer plugins" +msgstr "只有員工用户可以管理插件" + +#: plugin/installer.py:347 msgid "Plugin uninstalling is disabled" msgstr "插件卸載已禁用" -#: plugin/installer.py:341 +#: plugin/installer.py:351 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "插件無法卸載,因為它目前處於激活狀態" -#: plugin/installer.py:347 +#: plugin/installer.py:357 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "不可解除安裝此模組(屬於強制)" -#: plugin/installer.py:352 +#: plugin/installer.py:362 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "不可解除安裝此模組(範例模組)" -#: plugin/installer.py:357 +#: plugin/installer.py:367 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "不可解除安裝此模組(內建模組)" -#: plugin/installer.py:361 +#: plugin/installer.py:371 msgid "Plugin is not installed" msgstr "模組尚未安裝" -#: plugin/installer.py:379 +#: plugin/installer.py:389 msgid "Plugin installation not found" msgstr "找不到模組安裝紀錄" -#: plugin/installer.py:395 +#: plugin/installer.py:405 msgid "Uninstalled plugin successfully" msgstr "插件卸載成功" @@ -7655,7 +7841,7 @@ msgstr "插件的鍵" #: plugin/models.py:55 msgid "Name of the plugin" -msgstr "" +msgstr "外掛名稱" #: plugin/models.py:62 plugin/serializers.py:119 msgid "Package Name" @@ -7689,21 +7875,21 @@ msgstr "軟件包插件" msgid "Plugin" msgstr "插件" -#: plugin/plugin.py:386 +#: plugin/plugin.py:388 msgid "No author found" msgstr "未找到作者" -#: plugin/registry.py:781 +#: plugin/registry.py:786 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "插件 '{p}' 與當前 InvenTree 版本{v} 不兼容" -#: plugin/registry.py:784 +#: plugin/registry.py:789 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "插件所需最低版本 {v}" -#: plugin/registry.py:786 +#: plugin/registry.py:791 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "插件所需最高版本 {v}" @@ -7882,57 +8068,57 @@ msgstr "安裝尚未確認" #: plugin/serializers.py:152 msgid "Either packagename or URL must be provided" -msgstr "" +msgstr "必須提供套件名稱或 URL" -#: plugin/serializers.py:188 +#: plugin/serializers.py:191 msgid "Full reload" msgstr "完全重載" -#: plugin/serializers.py:189 +#: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" msgstr "執行插件庫的完整重載" -#: plugin/serializers.py:195 +#: plugin/serializers.py:198 msgid "Force reload" msgstr "強制重載" -#: plugin/serializers.py:197 +#: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" msgstr "強制重載插件庫,即使已經加載" -#: plugin/serializers.py:204 +#: plugin/serializers.py:207 msgid "Collect plugins" msgstr "收集插件" -#: plugin/serializers.py:205 +#: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" msgstr "收集插件並添加到註冊表中" -#: plugin/serializers.py:233 +#: plugin/serializers.py:236 msgid "Activate Plugin" msgstr "激活插件" -#: plugin/serializers.py:234 +#: plugin/serializers.py:237 msgid "Activate this plugin" msgstr "激活此插件" -#: plugin/serializers.py:243 +#: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" msgstr "強制模組不可停用" -#: plugin/serializers.py:261 +#: plugin/serializers.py:264 msgid "Delete configuration" msgstr "刪除配置" -#: plugin/serializers.py:262 +#: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" msgstr "從數據庫中刪除插件配置" -#: plugin/serializers.py:293 +#: plugin/serializers.py:299 msgid "The user for which this setting applies" msgstr "此設定所適用的使用者" -#: report/api.py:44 report/serializers.py:102 report/serializers.py:152 +#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 msgid "Items" msgstr "項目" @@ -7948,7 +8134,7 @@ msgstr "插件不支持標籤打印" msgid "Invalid label dimensions" msgstr "無效的標籤尺寸" -#: report/api.py:183 report/api.py:267 +#: report/api.py:183 report/api.py:272 msgid "No valid items provided to template" msgstr "沒有有效的項目提供到模板" @@ -7972,152 +8158,156 @@ msgstr "字母" msgid "Template file with this name already exists" msgstr "已存在具有此名稱的模板" -#: report/models.py:217 +#: report/models.py:220 msgid "Template name" msgstr "模版名稱" -#: report/models.py:223 +#: report/models.py:226 msgid "Template description" msgstr "模板説明" -#: report/models.py:229 +#: report/models.py:232 msgid "Revision number (auto-increments)" msgstr "修訂編號 (自動增量)" -#: report/models.py:235 +#: report/models.py:238 msgid "Attach to Model on Print" msgstr "打印時附加到模型" -#: report/models.py:237 +#: report/models.py:240 msgid "Save report output as an attachment against linked model instance when printing" msgstr "打印時將報告輸出保存為附件與鏈接模型實例" -#: report/models.py:281 +#: report/models.py:286 msgid "Filename Pattern" msgstr "文件名樣式" -#: report/models.py:282 +#: report/models.py:287 msgid "Pattern for generating filenames" msgstr "生成文件名模式" -#: report/models.py:287 +#: report/models.py:292 msgid "Template is enabled" msgstr "模板已啓用" -#: report/models.py:294 +#: report/models.py:299 msgid "Target model type for template" msgstr "模版的目標模型類型" -#: report/models.py:314 +#: report/models.py:319 msgid "Filters" msgstr "篩選器" -#: report/models.py:315 +#: report/models.py:320 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "模版查詢篩選器 (逗號分隔的鍵值對列表)" -#: report/models.py:374 report/models.py:670 +#: report/models.py:379 report/models.py:700 msgid "Template file" msgstr "模板包文件" -#: report/models.py:382 +#: report/models.py:387 msgid "Page size for PDF reports" msgstr "PDF 報告的頁面大小" -#: report/models.py:388 +#: report/models.py:393 msgid "Render report in landscape orientation" msgstr "橫向渲染報告" -#: report/models.py:393 +#: report/models.py:398 msgid "Merge" msgstr "合併" -#: report/models.py:394 +#: report/models.py:399 msgid "Render a single report against selected items" msgstr "針對所選項目產出合併單一報告" -#: report/models.py:449 +#: report/models.py:466 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "由模板 {self.name} 產生的報告" -#: report/models.py:546 report/models.py:585 report/models.py:586 +#: report/models.py:576 report/models.py:615 report/models.py:616 msgid "Template syntax error" msgstr "模板語法錯誤" -#: report/models.py:553 report/models.py:592 +#: report/models.py:583 report/models.py:622 msgid "Error rendering report" msgstr "報告渲染錯誤" -#: report/models.py:612 +#: report/models.py:643 msgid "Error generating report" msgstr "生成報告錯誤" -#: report/models.py:644 +#: report/models.py:674 msgid "Error merging report outputs" msgstr "合併報告輸出時發生錯誤" -#: report/models.py:676 +#: report/models.py:706 msgid "Width [mm]" msgstr "寬度 [mm]" -#: report/models.py:677 +#: report/models.py:707 msgid "Label width, specified in mm" msgstr "標籤寬度,以毫米為單位。" -#: report/models.py:683 +#: report/models.py:713 msgid "Height [mm]" msgstr "高度 [mm]" -#: report/models.py:684 +#: report/models.py:714 msgid "Label height, specified in mm" msgstr "標籤高度,以毫米為單位。" -#: report/models.py:789 +#: report/models.py:828 msgid "Error printing labels" msgstr "列印標籤時發生錯誤" -#: report/models.py:808 +#: report/models.py:847 msgid "Snippet" msgstr "代碼片段" -#: report/models.py:809 +#: report/models.py:848 msgid "Report snippet file" msgstr "報告代碼片段文件" -#: report/models.py:816 +#: report/models.py:855 msgid "Snippet file description" msgstr "代碼片段文件描述" -#: report/models.py:834 +#: report/models.py:873 msgid "Asset" msgstr "資產" -#: report/models.py:835 +#: report/models.py:874 msgid "Report asset file" msgstr "報告資產文件" -#: report/models.py:842 +#: report/models.py:881 msgid "Asset file description" msgstr "資產文件描述" -#: report/serializers.py:95 +#: report/serializers.py:37 +msgid "User must be authenticated to save report templates" +msgstr "使用者必須經過驗證才能儲存報告範本" + +#: report/serializers.py:118 msgid "Select report template" msgstr "選擇報表模板" -#: report/serializers.py:103 report/serializers.py:153 +#: report/serializers.py:126 report/serializers.py:176 msgid "List of item primary keys to include in the report" msgstr "要包含在報告中的項目主鍵列表" -#: report/serializers.py:136 +#: report/serializers.py:159 msgid "Select label template" msgstr "選擇標籤模板" -#: report/serializers.py:144 +#: report/serializers.py:167 msgid "Printing Plugin" msgstr "打印插件" -#: report/serializers.py:145 +#: report/serializers.py:168 msgid "Select plugin to use for label printing" msgstr "選擇用於標籤打印的插件" @@ -8190,7 +8380,7 @@ 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:1088 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 #: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "序列號" @@ -8215,7 +8405,7 @@ msgstr "庫存項測試報告" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:630 +#: stock/serializers.py:655 msgid "Installed Items" msgstr "已安裝的項目" @@ -8248,186 +8438,198 @@ msgstr "無結果 (必填)" msgid "No result" msgstr "沒有結果" -#: report/templatetags/report.py:169 -msgid "Asset file does not exist" -msgstr "資產文件不存在" +#: report/templatetags/report.py:166 +msgid "Invalid media file path" +msgstr "無效的媒體檔案路徑" -#: report/templatetags/report.py:226 report/templatetags/report.py:302 +#: report/templatetags/report.py:185 +msgid "Invalid static file path" +msgstr "無效的靜態檔案路徑" + +#: report/templatetags/report.py:287 +msgid "Asset file not found" +msgstr "找不到資產檔案" + +#: report/templatetags/report.py:345 report/templatetags/report.py:461 msgid "Image file not found" msgstr "找不到圖片文件" -#: report/templatetags/report.py:327 +#: report/templatetags/report.py:430 +msgid "No image file specified" +msgstr "未指定影像檔案" + +#: report/templatetags/report.py:455 msgid "part_image tag requires a Part instance" msgstr "parpart_image 標籤需要一個零件實例" -#: report/templatetags/report.py:384 +#: report/templatetags/report.py:553 msgid "company_image tag requires a Company instance" msgstr "公司_圖片標籤需要一個公司實例" -#: stock/api.py:288 +#: stock/api.py:287 msgid "Filter by location depth" msgstr "按位置深度篩選" -#: stock/api.py:308 +#: stock/api.py:307 msgid "Filter by top-level locations" msgstr "按頂級位置篩選" -#: stock/api.py:323 +#: stock/api.py:322 msgid "Include sub-locations in filtered results" msgstr "在篩選結果中包含子地點" -#: stock/api.py:344 stock/serializers.py:1202 +#: stock/api.py:343 stock/serializers.py:1227 msgid "Parent Location" msgstr "上級地點" -#: stock/api.py:345 +#: stock/api.py:344 msgid "Filter by parent location" msgstr "按上級位置篩選" -#: stock/api.py:605 +#: stock/api.py:604 msgid "Part name (case insensitive)" msgstr "零件名稱(不分大小寫)" -#: stock/api.py:611 +#: stock/api.py:610 msgid "Part name contains (case insensitive)" msgstr "零件名稱包含(不分大小寫)" -#: stock/api.py:617 +#: stock/api.py:616 msgid "Part name (regex)" msgstr "零件名稱(正則)" -#: stock/api.py:622 +#: stock/api.py:621 msgid "Part IPN (case insensitive)" msgstr "零件 IPN(不分大小寫)" -#: stock/api.py:628 +#: stock/api.py:627 msgid "Part IPN contains (case insensitive)" msgstr "零件 IPN 包含(不分大小寫)" -#: stock/api.py:634 +#: stock/api.py:633 msgid "Part IPN (regex)" msgstr "零件 IPN(正則)" -#: stock/api.py:646 +#: stock/api.py:645 msgid "Minimum stock" msgstr "最小庫存" -#: stock/api.py:650 +#: stock/api.py:649 msgid "Maximum stock" msgstr "最大庫存" -#: stock/api.py:653 +#: stock/api.py:652 msgid "Status Code" msgstr "狀態代碼" -#: stock/api.py:693 +#: stock/api.py:692 msgid "External Location" msgstr "外部地點" -#: stock/api.py:792 +#: stock/api.py:791 msgid "Consumed by Build Order" msgstr "被生產工單消耗" -#: stock/api.py:802 +#: stock/api.py:801 msgid "Installed in other stock item" msgstr "已安裝於其他庫存項" -#: stock/api.py:891 +#: stock/api.py:890 msgid "Part Tree" msgstr "零件樹" -#: stock/api.py:913 +#: stock/api.py:912 msgid "Updated before" msgstr "更新時間早於" -#: stock/api.py:917 +#: stock/api.py:916 msgid "Updated after" msgstr "更新時間晚於" -#: stock/api.py:921 +#: stock/api.py:920 msgid "Stocktake Before" msgstr "盤點日期早於" -#: stock/api.py:925 +#: stock/api.py:924 msgid "Stocktake After" msgstr "盤點日期晚於" -#: stock/api.py:930 +#: stock/api.py:929 msgid "Expiry date before" msgstr "過期日期前" -#: stock/api.py:934 +#: stock/api.py:933 msgid "Expiry date after" msgstr "過期日期後" -#: stock/api.py:937 stock/serializers.py:635 +#: stock/api.py:936 stock/serializers.py:660 msgid "Stale" msgstr "過期" -#: stock/api.py:963 +#: stock/api.py:962 msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" +msgstr "提供一個 StockItem PK 以排除該項目及其所有子項目" + +#: stock/api.py:980 +msgid "Cascade Locations" +msgstr "級聯位置" #: stock/api.py:981 -msgid "Cascade Locations" -msgstr "" - -#: stock/api.py:982 msgid "If true, include items in child locations of the given location" -msgstr "" +msgstr "若為 true,則包含給定位置的子位置中的項目" -#: stock/api.py:988 +#: stock/api.py:987 msgid "Filter by numeric Location ID or the literal 'null'" -msgstr "" +msgstr "依數字位置 ID 或常值 'null' 篩選" -#: stock/api.py:1084 +#: stock/api.py:1087 msgid "Quantity is required" msgstr "請先輸入數量" -#: stock/api.py:1089 +#: stock/api.py:1092 msgid "Valid part must be supplied" msgstr "必須提供有效的零件" -#: stock/api.py:1120 +#: stock/api.py:1123 msgid "The given supplier part does not exist" msgstr "給定的供應商零件不存在" -#: stock/api.py:1130 +#: stock/api.py:1133 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "供應商零件有定義的包裝大小,但 use_pack_size 標誌未設置" -#: stock/api.py:1162 +#: stock/api.py:1165 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "不能為不可跟蹤的零件提供序列號" -#: stock/api.py:1401 +#: stock/api.py:1409 msgid "Include Installed" -msgstr "" +msgstr "包含已安裝" -#: stock/api.py:1403 +#: stock/api.py:1411 msgid "If true, include test results for items installed underneath the given stock item" -msgstr "" +msgstr "若為 true,則包含安裝在給定庫存項目下方的項目的測試結果" -#: stock/api.py:1410 +#: stock/api.py:1418 msgid "Filter by numeric Stock Item ID" -msgstr "" +msgstr "使用數字庫存品項 ID 做過濾" -#: stock/api.py:1431 +#: stock/api.py:1439 #, python-brace-format msgid "Stock item with ID {id} does not exist" -msgstr "" +msgstr "庫存品項 ID {id} 不存在" -#: stock/api.py:1508 +#: stock/api.py:1516 msgid "Include Part Variants" -msgstr "" +msgstr "包括零件變數" -#: stock/api.py:1538 +#: stock/api.py:1546 msgid "Date after" -msgstr "" +msgstr "日前之後" -#: stock/api.py:1542 +#: stock/api.py:1550 msgid "Date before" -msgstr "" +msgstr "日期之前" #: stock/models.py:73 msgid "Stock Location type" @@ -8441,19 +8643,19 @@ msgstr "庫存地點類型" msgid "Default icon for all locations that have no icon set (optional)" msgstr "為所有沒有圖標的位置設置默認圖標(可選)" -#: stock/models.py:147 stock/models.py:1050 +#: stock/models.py:147 stock/models.py:1076 msgid "Stock Location" msgstr "庫存地點" -#: stock/models.py:148 users/ruleset.py:29 +#: stock/models.py:148 users/ruleset.py:31 msgid "Stock Locations" msgstr "庫存地點" -#: stock/models.py:197 stock/models.py:1215 +#: stock/models.py:197 stock/models.py:1241 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1216 +#: stock/models.py:198 stock/models.py:1242 msgid "Select Owner" msgstr "選擇所有者" @@ -8461,7 +8663,7 @@ msgstr "選擇所有者" 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:497 +#: stock/models.py:213 users/models.py:495 msgid "External" msgstr "外部" @@ -8481,274 +8683,282 @@ msgstr "該位置的庫存地點類型" msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "您不能將此庫存地點設置為結構性,因為某些庫存項已經位於它!" -#: stock/models.py:583 +#: stock/models.py:537 +msgid "Serialized stock items cannot be deleted" +msgstr "" + +#: stock/models.py:674 #, python-brace-format msgid "{field} does not exist" msgstr "{field} 不存在" -#: stock/models.py:596 +#: stock/models.py:687 msgid "Part must be specified" msgstr "必須指定零件" -#: stock/models.py:909 +#: stock/models.py:924 msgid "Stock items cannot be located into structural stock locations!" msgstr "庫存項不能存放在結構性庫存地點!" -#: stock/models.py:936 stock/serializers.py:455 +#: stock/models.py:945 +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 msgid "Stock item cannot be created for virtual parts" msgstr "無法為虛擬零件創建庫存項" -#: stock/models.py:953 +#: stock/models.py:979 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "零件類型 ('{self.supplier_part.part}') 必須為 {self.part}" -#: stock/models.py:963 stock/models.py:976 +#: stock/models.py:989 stock/models.py:1002 msgid "Quantity must be 1 for item with a serial number" msgstr "有序列號的項目的數量必須是1" -#: stock/models.py:966 +#: stock/models.py:992 msgid "Serial number cannot be set if quantity greater than 1" msgstr "如果數量大於1,則不能設置序列號" -#: stock/models.py:988 +#: stock/models.py:1014 msgid "Item cannot belong to itself" msgstr "項目不能屬於其自身" -#: stock/models.py:993 +#: stock/models.py:1019 msgid "Item must have a build reference if is_building=True" msgstr "如果is_building=True,則項必須具有構建引用" -#: stock/models.py:1006 +#: stock/models.py:1032 msgid "Build reference does not point to the same part object" msgstr "構建引用未指向同一零件對象" -#: stock/models.py:1020 +#: stock/models.py:1046 msgid "Parent Stock Item" msgstr "母庫存項目" -#: stock/models.py:1032 +#: stock/models.py:1058 msgid "Base part" msgstr "基礎零件" -#: stock/models.py:1042 +#: stock/models.py:1068 msgid "Select a matching supplier part for this stock item" msgstr "為此庫存項目選擇匹配的供應商零件" -#: stock/models.py:1054 +#: stock/models.py:1080 msgid "Where is this stock item located?" msgstr "這個庫存物品在哪裏?" -#: stock/models.py:1062 stock/serializers.py:1638 +#: stock/models.py:1088 stock/serializers.py:1682 msgid "Packaging this stock item is stored in" msgstr "包裝此庫存物品存儲在" -#: stock/models.py:1068 +#: stock/models.py:1094 msgid "Installed In" msgstr "安裝於" -#: stock/models.py:1073 +#: stock/models.py:1099 msgid "Is this item installed in another item?" msgstr "此項目是否安裝在另一個項目中?" -#: stock/models.py:1092 +#: stock/models.py:1118 msgid "Serial number for this item" msgstr "此項目的序列號" -#: stock/models.py:1109 stock/serializers.py:1623 +#: stock/models.py:1135 stock/serializers.py:1667 msgid "Batch code for this stock item" msgstr "此庫存項的批號" -#: stock/models.py:1114 +#: stock/models.py:1140 msgid "Stock Quantity" msgstr "庫存數量" -#: stock/models.py:1124 +#: stock/models.py:1150 msgid "Source Build" msgstr "源代碼構建" -#: stock/models.py:1127 +#: stock/models.py:1153 msgid "Build for this stock item" msgstr "為此庫存項目構建" -#: stock/models.py:1134 +#: stock/models.py:1160 msgid "Consumed By" msgstr "消費者" -#: stock/models.py:1137 +#: stock/models.py:1163 msgid "Build order which consumed this stock item" msgstr "構建消耗此庫存項的生產訂單" -#: stock/models.py:1146 +#: stock/models.py:1172 msgid "Source Purchase Order" msgstr "採購訂單來源" -#: stock/models.py:1150 +#: stock/models.py:1176 msgid "Purchase order for this stock item" msgstr "此庫存商品的採購訂單" -#: stock/models.py:1156 +#: stock/models.py:1182 msgid "Destination Sales Order" msgstr "目的地銷售訂單" -#: stock/models.py:1167 +#: stock/models.py:1193 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "庫存物品的到期日。在此日期之後,庫存將被視為過期" -#: stock/models.py:1185 +#: stock/models.py:1211 msgid "Delete on deplete" msgstr "耗盡時刪除" -#: stock/models.py:1186 +#: stock/models.py:1212 msgid "Delete this Stock Item when stock is depleted" msgstr "當庫存耗盡時刪除此庫存項" -#: stock/models.py:1207 +#: stock/models.py:1233 msgid "Single unit purchase price at time of purchase" msgstr "購買時一個單位的價格" -#: stock/models.py:1238 +#: stock/models.py:1264 msgid "Converted to part" msgstr "轉換為零件" -#: stock/models.py:1440 +#: stock/models.py:1466 msgid "Quantity exceeds available stock" msgstr "數量超過可用庫存" -#: stock/models.py:1891 +#: stock/models.py:1917 msgid "Part is not set as trackable" msgstr "零件未設置為可跟蹤" -#: stock/models.py:1897 +#: stock/models.py:1923 msgid "Quantity must be integer" msgstr "數量必須是整數" -#: stock/models.py:1905 +#: stock/models.py:1931 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "數量不得超過現有庫存量 ({self.quantity})" -#: stock/models.py:1911 +#: stock/models.py:1937 msgid "Serial numbers must be provided as a list" msgstr "序列號需以清單提供" -#: stock/models.py:1916 +#: stock/models.py:1942 msgid "Quantity does not match serial numbers" msgstr "數量不匹配序列號" -#: stock/models.py:1934 +#: stock/models.py:1960 msgid "Cannot assign stock to structural location" -msgstr "" +msgstr "無法將庫存分配到結構位置" -#: stock/models.py:2051 stock/models.py:3021 +#: stock/models.py:2077 stock/models.py:3047 msgid "Test template does not exist" msgstr "測試模板不存在" -#: stock/models.py:2069 +#: stock/models.py:2095 msgid "Stock item has been assigned to a sales order" msgstr "庫存項已分配到銷售訂單" -#: stock/models.py:2073 +#: stock/models.py:2099 msgid "Stock item is installed in another item" msgstr "庫存項已安裝在另一個項目中" -#: stock/models.py:2076 +#: stock/models.py:2102 msgid "Stock item contains other items" msgstr "庫存項包含其他項目" -#: stock/models.py:2079 +#: stock/models.py:2105 msgid "Stock item has been assigned to a customer" msgstr "庫存項已分配給客户" -#: stock/models.py:2082 stock/models.py:2268 +#: stock/models.py:2108 stock/models.py:2294 msgid "Stock item is currently in production" msgstr "庫存項目前正在生產" -#: stock/models.py:2085 +#: stock/models.py:2111 msgid "Serialized stock cannot be merged" msgstr "序列化的庫存不能合併" -#: stock/models.py:2092 stock/serializers.py:1493 +#: stock/models.py:2118 stock/serializers.py:1537 msgid "Duplicate stock items" msgstr "複製庫存項" -#: stock/models.py:2096 +#: stock/models.py:2122 msgid "Stock items must refer to the same part" msgstr "庫存項必須指相同零件" -#: stock/models.py:2104 +#: stock/models.py:2130 msgid "Stock items must refer to the same supplier part" msgstr "庫存項必須是同一供應商的零件" -#: stock/models.py:2109 +#: stock/models.py:2135 msgid "Stock status codes must match" msgstr "庫存狀態碼必須匹配" -#: stock/models.py:2409 +#: stock/models.py:2435 msgid "StockItem cannot be moved as it is not in stock" msgstr "庫存項不能移動,因為它沒有庫存" -#: stock/models.py:2903 +#: stock/models.py:2929 msgid "Stock Item Tracking" msgstr "庫存項跟蹤" -#: stock/models.py:2953 +#: stock/models.py:2979 msgid "Entry notes" msgstr "條目註釋" -#: stock/models.py:2993 +#: stock/models.py:3019 msgid "Stock Item Test Result" msgstr "庫存項測試結果" -#: stock/models.py:3024 +#: stock/models.py:3050 msgid "Value must be provided for this test" msgstr "必須為此測試提供值" -#: stock/models.py:3028 +#: stock/models.py:3054 msgid "Attachment must be uploaded for this test" msgstr "測試附件必須上傳" -#: stock/models.py:3033 +#: stock/models.py:3059 msgid "Invalid value for this test" msgstr "此測試的值無效" -#: stock/models.py:3057 +#: stock/models.py:3083 msgid "Test result" msgstr "測試結果" -#: stock/models.py:3064 +#: stock/models.py:3090 msgid "Test output value" msgstr "測試輸出值" -#: stock/models.py:3072 stock/serializers.py:250 +#: stock/models.py:3098 stock/serializers.py:259 msgid "Test result attachment" msgstr "測驗結果附件" -#: stock/models.py:3076 +#: stock/models.py:3102 msgid "Test notes" msgstr "測試備註" -#: stock/models.py:3084 +#: stock/models.py:3110 msgid "Test station" msgstr "測試站" -#: stock/models.py:3085 +#: stock/models.py:3111 msgid "The identifier of the test station where the test was performed" msgstr "進行測試的測試站的標識符" -#: stock/models.py:3091 +#: stock/models.py:3117 msgid "Started" msgstr "已開始" -#: stock/models.py:3092 +#: stock/models.py:3118 msgid "The timestamp of the test start" msgstr "測試開始的時間戳" -#: stock/models.py:3098 +#: stock/models.py:3124 msgid "Finished" msgstr "已完成" -#: stock/models.py:3099 +#: stock/models.py:3125 msgid "The timestamp of the test finish" msgstr "測試結束的時間戳" @@ -8792,246 +9002,246 @@ msgstr "選擇要生成序列號的零件" msgid "Quantity of serial numbers to generate" msgstr "要生成的序列號的數量" -#: stock/serializers.py:236 +#: stock/serializers.py:246 msgid "Test template for this result" msgstr "此結果的測試模板" -#: stock/serializers.py:280 +#: stock/serializers.py:289 msgid "No matching test found for this part" -msgstr "" +msgstr "未找到與此零件相符的測試" -#: stock/serializers.py:284 +#: stock/serializers.py:293 msgid "Template ID or test name must be provided" msgstr "必須提供模板 ID 或測試名稱" -#: stock/serializers.py:294 +#: stock/serializers.py:303 msgid "The test finished time cannot be earlier than the test started time" msgstr "測試完成時間不能早於測試開始時間" -#: stock/serializers.py:416 +#: stock/serializers.py:427 msgid "Parent Item" msgstr "父項" -#: stock/serializers.py:417 +#: stock/serializers.py:428 msgid "Parent stock item" msgstr "父庫存項" -#: stock/serializers.py:440 +#: stock/serializers.py:454 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "添加時使用包裝尺寸:定義的數量是包裝的數量" -#: stock/serializers.py:442 +#: stock/serializers.py:456 msgid "Use pack size" msgstr "使用包裝數" -#: stock/serializers.py:449 stock/serializers.py:704 +#: stock/serializers.py:463 stock/serializers.py:729 msgid "Enter serial numbers for new items" msgstr "輸入新項目的序列號" -#: stock/serializers.py:557 +#: stock/serializers.py:571 msgid "Supplier Part Number" msgstr "供應商零件編號" -#: stock/serializers.py:627 users/models.py:187 +#: stock/serializers.py:652 users/models.py:185 msgid "Expired" msgstr "已過期" -#: stock/serializers.py:633 +#: stock/serializers.py:658 msgid "Child Items" msgstr "子項目" -#: stock/serializers.py:637 +#: stock/serializers.py:662 msgid "Tracking Items" msgstr "跟蹤項目" -#: stock/serializers.py:643 +#: stock/serializers.py:668 msgid "Purchase price of this stock item, per unit or pack" msgstr "此庫存商品的購買價格,單位或包裝" -#: stock/serializers.py:681 +#: stock/serializers.py:706 msgid "Enter number of stock items to serialize" msgstr "輸入要序列化的庫存項目數量" -#: stock/serializers.py:689 stock/serializers.py:732 stock/serializers.py:770 -#: stock/serializers.py:908 +#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 +#: stock/serializers.py:933 msgid "No stock item provided" msgstr "未提供庫存項" -#: stock/serializers.py:697 +#: stock/serializers.py:722 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "數量不得超過現有庫存量 ({q})" -#: stock/serializers.py:715 stock/serializers.py:1450 stock/serializers.py:1771 -#: stock/serializers.py:1820 +#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 +#: stock/serializers.py:1864 msgid "Destination stock location" msgstr "目標庫存位置" -#: stock/serializers.py:735 +#: stock/serializers.py:760 msgid "Serial numbers cannot be assigned to this part" msgstr "此零件不能分配序列號" -#: stock/serializers.py:755 +#: stock/serializers.py:780 msgid "Serial numbers already exist" msgstr "序列號已存在" -#: stock/serializers.py:805 +#: stock/serializers.py:830 msgid "Select stock item to install" msgstr "選擇要安裝的庫存項目" -#: stock/serializers.py:812 +#: stock/serializers.py:837 msgid "Quantity to Install" msgstr "安裝數量" -#: stock/serializers.py:813 +#: stock/serializers.py:838 msgid "Enter the quantity of items to install" msgstr "輸入要安裝的項目數量" -#: stock/serializers.py:818 stock/serializers.py:898 stock/serializers.py:1040 +#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 msgid "Add transaction note (optional)" msgstr "添加交易記錄 (可選)" -#: stock/serializers.py:826 +#: stock/serializers.py:851 msgid "Quantity to install must be at least 1" msgstr "安裝數量必須至少為1" -#: stock/serializers.py:834 +#: stock/serializers.py:859 msgid "Stock item is unavailable" msgstr "庫存項不可用" -#: stock/serializers.py:845 +#: stock/serializers.py:870 msgid "Selected part is not in the Bill of Materials" msgstr "所選零件不在物料清單中" -#: stock/serializers.py:858 +#: stock/serializers.py:883 msgid "Quantity to install must not exceed available quantity" msgstr "安裝數量不得超過可用數量" -#: stock/serializers.py:893 +#: stock/serializers.py:918 msgid "Destination location for uninstalled item" msgstr "已卸載項目的目標位置" -#: stock/serializers.py:931 +#: stock/serializers.py:956 msgid "Select part to convert stock item into" msgstr "選擇要將庫存項目轉換為的零件" -#: stock/serializers.py:944 +#: stock/serializers.py:969 msgid "Selected part is not a valid option for conversion" msgstr "所選零件不是有效的轉換選項" -#: stock/serializers.py:961 +#: stock/serializers.py:986 msgid "Cannot convert stock item with assigned SupplierPart" msgstr "無法轉換已分配供應商零件的庫存項" -#: stock/serializers.py:995 +#: stock/serializers.py:1020 msgid "Stock item status code" msgstr "庫存項狀態代碼" -#: stock/serializers.py:1024 +#: stock/serializers.py:1049 msgid "Select stock items to change status" msgstr "選擇要更改狀態的庫存項目" -#: stock/serializers.py:1030 +#: stock/serializers.py:1055 msgid "No stock items selected" msgstr "未選擇庫存商品" -#: stock/serializers.py:1137 stock/serializers.py:1208 +#: stock/serializers.py:1162 stock/serializers.py:1233 msgid "Sublocations" msgstr "轉租" -#: stock/serializers.py:1203 +#: stock/serializers.py:1228 msgid "Parent stock location" msgstr "上級庫存地點" -#: stock/serializers.py:1322 +#: stock/serializers.py:1366 msgid "Part must be salable" msgstr "零件必須可銷售" -#: stock/serializers.py:1326 +#: stock/serializers.py:1370 msgid "Item is allocated to a sales order" msgstr "物料已分配到銷售訂單" -#: stock/serializers.py:1330 +#: stock/serializers.py:1374 msgid "Item is allocated to a build order" msgstr "項目被分配到生產訂單中" -#: stock/serializers.py:1354 +#: stock/serializers.py:1398 msgid "Customer to assign stock items" msgstr "客户分配庫存項目" -#: stock/serializers.py:1360 +#: stock/serializers.py:1404 msgid "Selected company is not a customer" msgstr "所選公司不是客户" -#: stock/serializers.py:1368 +#: stock/serializers.py:1412 msgid "Stock assignment notes" msgstr "庫存分配説明" -#: stock/serializers.py:1378 stock/serializers.py:1666 +#: stock/serializers.py:1422 stock/serializers.py:1710 msgid "A list of stock items must be provided" msgstr "必須提供庫存物品清單" -#: stock/serializers.py:1457 +#: stock/serializers.py:1501 msgid "Stock merging notes" msgstr "庫存合併説明" -#: stock/serializers.py:1462 +#: stock/serializers.py:1506 msgid "Allow mismatched suppliers" msgstr "允許不匹配的供應商" -#: stock/serializers.py:1463 +#: stock/serializers.py:1507 msgid "Allow stock items with different supplier parts to be merged" msgstr "允許合併具有不同供應商零件的庫存項目" -#: stock/serializers.py:1468 +#: stock/serializers.py:1512 msgid "Allow mismatched status" msgstr "允許不匹配的狀態" -#: stock/serializers.py:1469 +#: stock/serializers.py:1513 msgid "Allow stock items with different status codes to be merged" msgstr "允許合併具有不同狀態代碼的庫存項目" -#: stock/serializers.py:1479 +#: stock/serializers.py:1523 msgid "At least two stock items must be provided" msgstr "必須提供至少兩件庫存物品" -#: stock/serializers.py:1546 +#: stock/serializers.py:1590 msgid "No Change" msgstr "無更改" -#: stock/serializers.py:1584 +#: stock/serializers.py:1628 msgid "StockItem primary key value" msgstr "庫存項主鍵值" -#: stock/serializers.py:1597 +#: stock/serializers.py:1641 msgid "Stock item is not in stock" msgstr "庫存項無庫存" -#: stock/serializers.py:1600 +#: stock/serializers.py:1644 msgid "Stock item is already in stock" msgstr "庫存項已在庫" -#: stock/serializers.py:1614 +#: stock/serializers.py:1658 msgid "Quantity must not be negative" msgstr "數量不可為負" -#: stock/serializers.py:1656 +#: stock/serializers.py:1700 msgid "Stock transaction notes" msgstr "庫存交易記錄" -#: stock/serializers.py:1826 +#: stock/serializers.py:1870 msgid "Merge into existing stock" msgstr "合併至現有庫存" -#: stock/serializers.py:1827 +#: stock/serializers.py:1871 msgid "Merge returned items into existing stock items if possible" msgstr "可行時將退回項目併入現有庫存" -#: stock/serializers.py:1870 +#: stock/serializers.py:1914 msgid "Next Serial Number" msgstr "下一個序列號" -#: stock/serializers.py:1876 +#: stock/serializers.py:1920 msgid "Previous Serial Number" msgstr "上一個序列號" @@ -9089,7 +9299,7 @@ msgstr "已手動刪除庫存" #: stock/status_codes.py:56 msgid "Serialized stock items" -msgstr "" +msgstr "序列化庫存品項" #: stock/status_codes.py:58 msgid "Returned to stock" @@ -9369,227 +9579,247 @@ msgstr "最近使用令牌的時間" msgid "Revoked" msgstr "撤銷" -#: users/models.py:229 +#: users/models.py:227 msgid "Permission set" msgstr "權限設置" -#: users/models.py:242 +#: users/models.py:240 msgid "View" msgstr "查看" -#: users/models.py:242 +#: users/models.py:240 msgid "Permission to view items" msgstr "查看項目的權限" -#: users/models.py:246 +#: users/models.py:244 msgid "Add" msgstr "添加" -#: users/models.py:246 +#: users/models.py:244 msgid "Permission to add items" msgstr "添加項目的權限" -#: users/models.py:250 +#: users/models.py:248 msgid "Change" msgstr "更改" -#: users/models.py:252 +#: users/models.py:250 msgid "Permissions to edit items" msgstr "編輯項目的權限" -#: users/models.py:256 +#: users/models.py:254 msgid "Delete" msgstr "刪除" -#: users/models.py:258 +#: users/models.py:256 msgid "Permission to delete items" msgstr "刪除項目的權限" -#: users/models.py:495 +#: users/models.py:493 msgid "Bot" msgstr "機器人" -#: users/models.py:496 +#: users/models.py:494 msgid "Internal" msgstr "內部" -#: users/models.py:498 +#: users/models.py:496 msgid "Guest" msgstr "訪客" -#: users/models.py:507 +#: users/models.py:505 msgid "Language" msgstr "語言 LANG" -#: users/models.py:508 +#: users/models.py:506 msgid "Preferred language for the user" msgstr "使用者偏好語言" -#: users/models.py:513 +#: users/models.py:511 msgid "Theme" msgstr "主題" -#: users/models.py:514 +#: users/models.py:512 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Web 介面設定(JSON,請勿手動編輯)" -#: users/models.py:519 +#: users/models.py:517 msgid "Widgets" msgstr "小工具" -#: users/models.py:521 +#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "儀表板小工具設定(JSON,請勿手動編輯)" -#: users/models.py:528 +#: users/models.py:526 msgid "Display Name" msgstr "顯示名稱" -#: users/models.py:529 +#: users/models.py:527 msgid "Chosen display name for the user" msgstr "使用者自選顯示名稱" -#: users/models.py:535 +#: users/models.py:533 msgid "Position" msgstr "職稱" -#: users/models.py:536 +#: users/models.py:534 msgid "Main job title or position" msgstr "主要職稱或職位" -#: users/models.py:543 +#: users/models.py:541 msgid "User status message" msgstr "使用者狀態訊息" -#: users/models.py:550 +#: users/models.py:548 msgid "User location information" msgstr "使用者位置資訊" -#: users/models.py:555 +#: users/models.py:553 msgid "User is actively using the system" msgstr "使用者目前活躍" -#: users/models.py:562 +#: users/models.py:560 msgid "Preferred contact information for the user" msgstr "使用者偏好聯絡資訊" -#: users/models.py:568 +#: users/models.py:566 msgid "User Type" msgstr "使用者類型" -#: users/models.py:569 +#: users/models.py:567 msgid "Which type of user is this?" msgstr "此為哪種類型的使用者?" -#: users/models.py:575 +#: users/models.py:573 msgid "Organisation" msgstr "組織" -#: users/models.py:576 +#: users/models.py:574 msgid "Users primary organisation/affiliation" msgstr "使用者主要所屬組織" -#: users/models.py:584 +#: users/models.py:582 msgid "Primary Group" msgstr "主要群組" -#: users/models.py:585 +#: users/models.py:583 msgid "Primary group for the user" msgstr "使用者的主要群組" -#: users/ruleset.py:26 +#: users/ruleset.py:27 msgid "Admin" msgstr "管理員" -#: users/ruleset.py:32 +#: users/ruleset.py:30 +msgid "Bills of Material" +msgstr "" + +#: users/ruleset.py:34 msgid "Purchase Orders" msgstr "採購訂單" -#: users/ruleset.py:33 +#: users/ruleset.py:35 msgid "Sales Orders" msgstr "銷售訂單" -#: users/ruleset.py:34 +#: users/ruleset.py:36 msgid "Return Orders" msgstr "退貨訂單" -#: users/serializers.py:190 +#: users/serializers.py:186 msgid "Username" msgstr "用户名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First Name" msgstr "名" -#: users/serializers.py:193 +#: users/serializers.py:189 msgid "First name of the user" msgstr "用户的名字(不包括姓氏)" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last Name" msgstr "姓" -#: users/serializers.py:197 +#: users/serializers.py:193 msgid "Last name of the user" msgstr "用户的姓氏" -#: users/serializers.py:201 +#: users/serializers.py:197 msgid "Email address of the user" msgstr "用户的電子郵件地址" -#: users/serializers.py:309 -msgid "Staff" -msgstr "職員" +#: users/serializers.py:240 +msgid "User must be authenticated" +msgstr "使用者必須經過驗證" -#: users/serializers.py:310 -msgid "Does this user have staff permissions" -msgstr "此用户是否擁有員工權限" +#: users/serializers.py:249 +msgid "Only a superuser can create a token for another user" +msgstr "只有超級使用者可以為其他使用者建立權杖" -#: users/serializers.py:315 +#: users/serializers.py:329 +msgid "Administrator" +msgstr "管理員" + +#: users/serializers.py:330 +msgid "Does this user have administrative permissions" +msgstr "此使用者是否具有管理權限" + +#: users/serializers.py:335 users/serializers.py:424 msgid "Superuser" msgstr "超級用户" -#: users/serializers.py:315 +#: users/serializers.py:335 users/serializers.py:425 msgid "Is this user a superuser" msgstr "此用户是否為超級用户" -#: users/serializers.py:319 +#: users/serializers.py:339 users/serializers.py:432 msgid "Is this user account active" msgstr "此用户帳户是否已激活" -#: users/serializers.py:331 +#: users/serializers.py:351 msgid "Only a superuser can adjust this field" msgstr "僅超級使用者可調整此欄位" -#: users/serializers.py:359 +#: users/serializers.py:379 msgid "Password" msgstr "密碼" -#: users/serializers.py:360 +#: users/serializers.py:380 msgid "Password for the user" msgstr "使用者密碼" -#: users/serializers.py:366 +#: users/serializers.py:386 msgid "Override warning" msgstr "忽略警告" -#: users/serializers.py:367 +#: users/serializers.py:387 msgid "Override the warning about password rules" msgstr "忽略密碼規則警告" -#: users/serializers.py:423 +#: users/serializers.py:417 +msgid "Staff" +msgstr "員工" + +#: users/serializers.py:418 +msgid "Does this user have staff permissions" +msgstr "此使用者是否具有員工權限" + +#: users/serializers.py:468 msgid "You do not have permission to create users" msgstr "您沒有建立使用者的權限" -#: users/serializers.py:444 +#: users/serializers.py:489 msgid "Your account has been created." msgstr "您的帳號已經建立完成。" -#: users/serializers.py:446 +#: users/serializers.py:491 msgid "Please use the password reset function to login" msgstr "請使用重設密碼功能來登入" -#: users/serializers.py:452 +#: users/serializers.py:497 msgid "Welcome to InvenTree" msgstr "歡迎使用 InvenTree" diff --git a/src/backend/InvenTree/machine/api.py b/src/backend/InvenTree/machine/api.py index 24342cc3f9..bea28dfcfd 100644 --- a/src/backend/InvenTree/machine/api.py +++ b/src/backend/InvenTree/machine/api.py @@ -58,11 +58,11 @@ class MachineDetail(RetrieveUpdateDestroyAPI): def get_machine(machine_pk): """Get machine by pk. - Raises: - NotFound: If machine is not found - Returns: BaseMachineType: The machine instance in the registry + + Raises: + NotFound: If machine is not found """ machine = registry.get_machine(machine_pk) @@ -98,7 +98,7 @@ class MachineSettingList(APIView): all_settings.extend(list(settings_dict.values())) results = MachineSerializers.MachineSettingSerializer( - all_settings, many=True + list(all_settings), many=True ).data return Response(results) diff --git a/src/backend/InvenTree/machine/machine_types/label_printer.py b/src/backend/InvenTree/machine/machine_types/label_printer.py index f2499187b3..f598f5dd55 100644 --- a/src/backend/InvenTree/machine/machine_types/label_printer.py +++ b/src/backend/InvenTree/machine/machine_types/label_printer.py @@ -111,7 +111,7 @@ class LabelPrinterBaseDriver(BaseDriver): Returns: A class instance of a DRF serializer class, by default this an instance of self.PrintingOptionsSerializer using the *args, **kwargs if existing for this driver """ - return self.PrintingOptionsSerializer(*args, **kwargs) # type: ignore + return self.PrintingOptionsSerializer(*args, **kwargs) # --- helper functions @property diff --git a/src/backend/InvenTree/machine/serializers.py b/src/backend/InvenTree/machine/serializers.py index 669ffe0b75..9bfe97a749 100644 --- a/src/backend/InvenTree/machine/serializers.py +++ b/src/backend/InvenTree/machine/serializers.py @@ -138,7 +138,7 @@ class MachineSettingSerializer(GenericReferencedSettingSerializer): """Custom init method to make the config_type field read only.""" super().__init__(*args, **kwargs) - self.Meta.read_only_fields = ['config_type'] # type: ignore + self.Meta.read_only_fields = ['config_type'] class BaseMachineClassSerializer(serializers.Serializer): diff --git a/src/backend/InvenTree/machine/test_api.py b/src/backend/InvenTree/machine/test_api.py index 20e9330542..32a2809d2f 100644 --- a/src/backend/InvenTree/machine/test_api.py +++ b/src/backend/InvenTree/machine/test_api.py @@ -147,7 +147,7 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase): def test_machine_detail(self): """Test machine detail API endpoint.""" - self.assertFalse(len(MachineConfig.objects.all()), 0) + self.assertFalse(MachineConfig.objects.count(), 0) self.get( reverse('api-machine-detail', kwargs={'pk': self.placeholder_uuid}), expected_code=404, @@ -185,7 +185,7 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase): response = self.delete( reverse('api-machine-detail', kwargs={'pk': pk}), expected_code=204 ) - self.assertFalse(len(MachineConfig.objects.all()), 0) + self.assertFalse(MachineConfig.objects.count(), 0) # Create machine where the driver does not exist machine_data['driver'] = 'non-existent-driver' diff --git a/src/backend/InvenTree/machine/tests.py b/src/backend/InvenTree/machine/tests.py index 99f9decc35..120ab004b9 100755 --- a/src/backend/InvenTree/machine/tests.py +++ b/src/backend/InvenTree/machine/tests.py @@ -232,10 +232,10 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): machine = self.create_machine() # setup the label app - apps.get_app_config('report').create_default_labels() # type: ignore + apps.get_app_config('report').create_default_labels() plg_registry.reload_plugins() - config = cast(PluginConfig, plg_registry.get_plugin(plugin_ref).plugin_config()) # type: ignore + config = cast(PluginConfig, plg_registry.get_plugin(plugin_ref).plugin_config()) config.active = True config.save() diff --git a/src/backend/InvenTree/manage.py b/src/backend/InvenTree/manage.py index 9e1d7b6804..baf3c1583d 100755 --- a/src/backend/InvenTree/manage.py +++ b/src/backend/InvenTree/manage.py @@ -22,4 +22,8 @@ def main(): if __name__ == '__main__': - main() + try: + main() + except KeyboardInterrupt: + print('INVE-W15: Process interrupted by user.') + sys.exit(1) diff --git a/src/backend/InvenTree/order/admin.py b/src/backend/InvenTree/order/admin.py index 70b7b3c13b..875ebdb763 100644 --- a/src/backend/InvenTree/order/admin.py +++ b/src/backend/InvenTree/order/admin.py @@ -170,3 +170,41 @@ class ReturnOrderLineItemAdmin(admin.ModelAdmin): @admin.register(models.ReturnOrderExtraLine) class ReturnOrdeerExtraLineAdmin(GeneralExtraLineAdmin, admin.ModelAdmin): """Admin class for the ReturnOrderExtraLine model.""" + + +class TransferOrderLineItemInlineAdmin(admin.StackedInline): + """Inline admin class for the TransferOrderLineItem model.""" + + autocomplete_fields = ['part'] + + model = models.TransferOrderLineItem + extra = 0 + + +@admin.register(models.TransferOrder) +class TransferOrderAdmin(admin.ModelAdmin): + """Admin class for the TransferOrder model.""" + + exclude = ['reference_int', 'address', 'contact'] + + list_display = ( + 'reference', + 'status', + 'description', + 'take_from', + 'destination', + 'consume', + 'creation_date', + ) + + search_fields = ['reference', 'description'] + + inlines = [TransferOrderLineItemInlineAdmin] + + autocomplete_fields = [ + 'created_by', + 'take_from', + 'destination', + 'project_code', + 'responsible', + ] diff --git a/src/backend/InvenTree/order/api.py b/src/backend/InvenTree/order/api.py index 854c8d906c..55bbf8db00 100644 --- a/src/backend/InvenTree/order/api.py +++ b/src/backend/InvenTree/order/api.py @@ -18,10 +18,12 @@ from django_ical.views import ICalFeed from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import extend_schema, extend_schema_field from rest_framework import status +from rest_framework.exceptions import NotFound from rest_framework.response import Response import build.models import common.models +import common.serializers import common.settings import company.models import stock.models as stock_models @@ -30,12 +32,8 @@ from data_exporter.mixins import DataExportViewMixin from generic.states.api import StatusView from InvenTree.api import BulkUpdateMixin, ListCreateDestroyAPIView, ParameterListMixin from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration -from InvenTree.filters import ( - SEARCH_ORDER_FILTER, - SEARCH_ORDER_FILTER_ALIAS, - InvenTreeDateFilter, -) -from InvenTree.helpers import str2bool +from InvenTree.filters import SEARCH_ORDER_FILTER, InvenTreeDateFilter +from InvenTree.helpers import current_date, str2bool from InvenTree.helpers_model import construct_absolute_url, get_base_url from InvenTree.mixins import ( CreateAPI, @@ -53,6 +51,8 @@ from order.status_codes import ( ReturnOrderStatus, SalesOrderStatus, SalesOrderStatusGroups, + TransferOrderStatus, + TransferOrderStatusGroups, ) from part.models import Part from users.models import Owner @@ -79,7 +79,9 @@ class GeneralExtraLineList(SerializerContextMixin, DataExportViewMixin): filter_backends = SEARCH_ORDER_FILTER - ordering_fields = ['quantity', 'notes', 'reference'] + ordering_fields = ['quantity', 'notes', 'reference', 'line'] + + ordering_field_aliases = {'line': ['line_int', 'line']} search_fields = ['quantity', 'notes', 'reference', 'description'] @@ -223,6 +225,14 @@ class OrderFilter(FilterSet): label=_('Target Date After'), field_name='target_date', lookup_expr='gt' ) + updated_before = InvenTreeDateFilter( + label=_('Updated Before'), field_name='updated_at', lookup_expr='lt' + ) + + updated_after = InvenTreeDateFilter( + label=_('Updated After'), field_name='updated_at', lookup_expr='gt' + ) + min_date = InvenTreeDateFilter(label=_('Min Date'), method='filter_min_date') def filter_min_date(self, queryset, name, value): @@ -386,7 +396,7 @@ class PurchaseOrderList( """ filterset_class = PurchaseOrderFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = PurchaseOrderOutputOptions ordering_field_aliases = { @@ -415,6 +425,7 @@ class PurchaseOrderList( 'responsible', 'total_price', 'project_code', + 'updated_at', ] ordering = '-reference' @@ -695,7 +706,7 @@ class PurchaseOrderLineItemList( serializer.data, status=status.HTTP_201_CREATED, headers=headers ) - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_field_aliases = { 'MPN': 'part__manufacturer_part__MPN', @@ -705,6 +716,7 @@ class PurchaseOrderLineItemList( 'order': 'order__reference', 'status': 'order__status', 'complete_date': 'order__complete_date', + 'line': ['line_int', 'line', 'part__SKU'], } ordering_fields = [ @@ -721,6 +733,7 @@ class PurchaseOrderLineItemList( 'order', 'status', 'complete_date', + 'line', ] search_fields = [ @@ -854,7 +867,7 @@ class SalesOrderList( """ filterset_class = SalesOrderFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = SalesOrderOutputOptions ordering_field_aliases = { @@ -877,6 +890,7 @@ class SalesOrderList( 'shipment_date', 'total_price', 'project_code', + 'updated_at', ] search_fields = [ @@ -1038,7 +1052,7 @@ class SalesOrderLineItemList( filterset_class = SalesOrderLineItemFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = SalesOrderLineItemOutputOptions @@ -1054,6 +1068,7 @@ class SalesOrderLineItemList( 'reference', 'sale_price', 'target_date', + 'line', ] ordering_field_aliases = { @@ -1061,6 +1076,7 @@ class SalesOrderLineItemList( 'part': 'part__name', 'IPN': 'part__IPN', 'order': 'order__reference', + 'line': ['line_int', 'line', 'part__name'], } search_fields = ['part__name', 'quantity', 'reference'] @@ -1284,7 +1300,7 @@ class SalesOrderAllocationList( """API endpoint for listing SalesOrderAllocation objects.""" filterset_class = SalesOrderAllocationFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = SalesOrderAllocationOutputOptions ordering_fields = [ @@ -1394,7 +1410,7 @@ class SalesOrderShipmentList(SalesOrderShipmentMixin, ListCreateAPI): """API list endpoint for SalesOrderShipment model.""" filterset_class = SalesOrderShipmentFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_fields = ['reference', 'delivery_date', 'shipment_date', 'allocated_items'] search_fields = [ @@ -1415,20 +1431,46 @@ class SalesOrderShipmentComplete(CreateAPI): queryset = models.SalesOrderShipment.objects.all() serializer_class = serializers.SalesOrderShipmentCompleteSerializer + def get_shipment(self): + """Return the shipment associated with this endpoint.""" + try: + shipment = models.SalesOrderShipment.objects.get( + pk=self.kwargs.get('pk', None) + ) + except (ValueError, models.SalesOrderShipment.DoesNotExist): + raise NotFound(detail=_('Shipment not found')) + + return shipment + def get_serializer_context(self): """Pass the request object to the serializer.""" ctx = super().get_serializer_context() ctx['request'] = self.request - - try: - ctx['shipment'] = models.SalesOrderShipment.objects.get( - pk=self.kwargs.get('pk', None) - ) - except Exception: - pass + ctx['shipment'] = self.get_shipment() return ctx + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, request, *args, **kwargs): + """Override the post method to handle shipment completion.""" + shipment = self.get_shipment() + + serializer = self.get_serializer(shipment, data=request.data, partial=True) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + task_id = shipment.complete_shipment( + request.user, + tracking_number=data.get('tracking_number', shipment.tracking_number), + invoice_number=data.get('invoice_number', shipment.invoice_number), + link=data.get('link', shipment.link), + shipment_date=data.get('shipment_date', None) or current_date(), + delivery_date=data.get('delivery_date', shipment.delivery_date), + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + class ReturnOrderFilter(OrderFilter): """Custom API filters for the ReturnOrderList endpoint.""" @@ -1523,7 +1565,7 @@ class ReturnOrderList( """API endpoint for accessing a list of ReturnOrder objects.""" filterset_class = ReturnOrderFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = ReturnOrderOutputOptions @@ -1544,6 +1586,7 @@ class ReturnOrderList( 'target_date', 'complete_date', 'project_code', + 'updated_at', ] search_fields = [ @@ -1669,7 +1712,7 @@ class ReturnOrderLineItemList( filterset_class = ReturnOrderLineItemFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER output_options = ReturnOrderLineItemOutputOptions @@ -1680,9 +1723,11 @@ class ReturnOrderLineItemList( 'reference', 'target_date', 'received_date', + 'line', ] ordering_field_aliases = { + 'line': ['line_int', 'line', 'item__part__name'], 'part': 'item__part__name', 'IPN': 'item__part__IPN', 'stock': ['item__quantity', 'item__serial_int', 'item__serial'], @@ -1718,6 +1763,521 @@ class ReturnOrderExtraLineDetail(RetrieveUpdateDestroyAPI): serializer_class = serializers.ReturnOrderExtraLineSerializer +class TransferOrderFilter(OrderFilter): + """Custom API filters for the TransferOrderList endpoint.""" + + class Meta: + """Metaclass options.""" + + model = models.TransferOrder + fields = [] + + include_variants = rest_filters.BooleanFilter( + label=_('Include Variants'), method='filter_include_variants' + ) + + def filter_include_variants(self, queryset, name, value): + """Filter by whether or not to include variants of the selected part. + + Note: + - This filter does nothing by itself, and requires the 'part' filter to be set. + - Refer to the 'filter_part' method for more information. + """ + return queryset + + part = rest_filters.ModelChoiceFilter( + queryset=Part.objects.all(), field_name='part', method='filter_part' + ) + + @extend_schema_field(OpenApiTypes.INT) + def filter_part(self, queryset, name, part): + """Filter by selected 'part'. + + Note: + - If 'include_variants' is set to True, then all variants of the selected part will be included. + - Otherwise, just filter by the selected part. + """ + include_variants = str2bool(self.data.get('include_variants', False)) + + if include_variants: + parts = part.get_descendants(include_self=True) + else: + parts = Part.objects.filter(pk=part.pk) + + # Now that we have a queryset of parts, find all the matching return orders + line_items = models.TransferOrderLineItem.objects.filter(part__in=parts) + + # Generate a list of ID values for the matching transfer orders + transfer_orders = line_items.values_list('order', flat=True).distinct() + + # Now we have a list of matching IDs, filter the queryset + return queryset.filter(pk__in=transfer_orders) + + completed_before = InvenTreeDateFilter( + label=_('Completed Before'), field_name='complete_date', lookup_expr='lt' + ) + + completed_after = InvenTreeDateFilter( + label=_('Completed After'), field_name='complete_date', lookup_expr='gt' + ) + + +class TransferOrderMixin(SerializerContextMixin): + """Mixin class for TransferOrder endpoints.""" + + queryset = models.TransferOrder.objects.all() + serializer_class = serializers.TransferOrderSerializer + + def get_queryset(self, *args, **kwargs): + """Return annotated queryset for this endpoint.""" + queryset = super().get_queryset(*args, **kwargs) + queryset = serializers.TransferOrderSerializer.annotate_queryset(queryset) + queryset = queryset.prefetch_related('created_by', 'responsible') + + return queryset + + +class TransferOrderList( + TransferOrderMixin, + OrderCreateMixin, + DataExportViewMixin, + OutputOptionsMixin, + ParameterListMixin, + ListCreateAPI, +): + """API endpoint for accessing a list of TransferOrder objects.""" + + filterset_class = TransferOrderFilter + filter_backends = SEARCH_ORDER_FILTER + + # TODO: + # output_options = TransferOrderOutputOptions + + ordering_field_aliases = { + 'reference': ['reference_int', 'reference'], + 'project_code': ['project_code__code'], + } + + ordering_fields = [ + 'creation_date', + 'created_by', + 'reference', + 'line_items', + 'status', + 'start_date', + 'target_date', + 'complete_date', + 'project_code', + ] + + search_fields = ['reference', 'description', 'project_code__code'] + + ordering = '-reference' + + +class TransferOrderDetail( + TransferOrderMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI +): + """API endpoint for detail view of a single TransferOrder object.""" + + # output_options = TransferOrderOutputOptions + + +class TransferOrderContextMixin: + """Simple mixin class to add a TransferOrder to the serializer context.""" + + queryset = models.TransferOrder.objects.all() + + def get_serializer_context(self): + """Add the TransferOrder object to the serializer context.""" + context = super().get_serializer_context() + + # Pass the Transfer instance through to the serializer for validation + try: + context['order'] = models.TransferOrder.objects.get( + pk=self.kwargs.get('pk', None) + ) + except Exception: + pass + + context['request'] = self.request + + return context + + +class TransferOrderCancel(TransferOrderContextMixin, CreateAPI): + """API endpoint to cancel a TransferOrder.""" + + serializer_class = serializers.TransferOrderCancelSerializer + + +class TransferOrderHold(TransferOrderContextMixin, CreateAPI): + """API endpoint to hold a TransferOrder.""" + + serializer_class = serializers.TransferOrderHoldSerializer + + +class TransferOrderComplete(TransferOrderContextMixin, CreateAPI): + """API endpoint to complete a TransferOrder.""" + + serializer_class = serializers.TransferOrderCompleteSerializer + + +class TransferOrderIssue(TransferOrderContextMixin, CreateAPI): + """API endpoint to issue a Transfer Order.""" + + serializer_class = serializers.TransferOrderIssueSerializer + + +class TransferOrderAllocateSerials(TransferOrderContextMixin, CreateAPI): + """API endpoint to allocation stock items against a TransferOrder, by specifying serial numbers.""" + + queryset = models.TransferOrder.objects.none() + serializer_class = serializers.TransferOrderSerialAllocationSerializer + + +class TransferOrderAllocate(TransferOrderContextMixin, CreateAPI): + """API endpoint to allocate stock items against a TransferOrder. + + - The TransferOrder is specified in the URL + - See the TransferOrderAllocationSerializer class + """ + + queryset = models.TransferOrder.objects.none() + serializer_class = serializers.TransferOrderLineItemAllocationSerializer + + +class TransferOrderAllocationFilter(FilterSet): + """Custom filterset for the TransferOrderAllocationList endpoint.""" + + class Meta: + """Metaclass options.""" + + model = models.TransferOrderAllocation + fields = ['line', 'item'] + + order = rest_filters.ModelChoiceFilter( + queryset=models.TransferOrder.objects.all(), + field_name='line__order', + label=_('Order'), + ) + + include_variants = rest_filters.BooleanFilter( + label=_('Include Variants'), method='filter_include_variants' + ) + + def filter_include_variants(self, queryset, name, value): + """Filter by whether or not to include variants of the selected part. + + Note: + - This filter does nothing by itself, and requires the 'part' filter to be set. + - Refer to the 'filter_part' method for more information. + """ + return queryset + + part = rest_filters.ModelChoiceFilter( + queryset=Part.objects.all(), method='filter_part', label=_('Part') + ) + + @extend_schema_field(rest_framework.serializers.IntegerField(help_text=_('Part'))) + def filter_part(self, queryset, name, part): + """Filter by the 'part' attribute. + + Note: + - If "include_variants" is True, include all variants of the selected part + - Otherwise, just filter by the selected part + """ + include_variants = str2bool(self.data.get('include_variants', False)) + + if include_variants: + parts = part.get_descendants(include_self=True) + return queryset.filter(item__part__in=parts) + else: + return queryset.filter(item__part=part) + + outstanding = rest_filters.BooleanFilter( + label=_('Outstanding'), method='filter_outstanding' + ) + + def filter_outstanding(self, queryset, name, value): + """Filter by "outstanding" status (boolean).""" + if str2bool(value): + return queryset.filter( + line__order__status__in=TransferOrderStatusGroups.OPEN + # TODO: is there an additional filter here if we aren't using a "shipment" + # shipment__shipment_date=None, + ) + return queryset.exclude( + # TODO: is there an additional filter here if we aren't using a "shipment" + # shipment__shipment_date=None, + line__order__status__in=TransferOrderStatusGroups.OPEN + ) + + location = rest_filters.ModelChoiceFilter( + queryset=stock_models.StockLocation.objects.all(), + label=_('Location'), + method='filter_location', + ) + + @extend_schema_field( + rest_framework.serializers.IntegerField(help_text=_('Location')) + ) + def filter_location(self, queryset, name, location): + """Filter by the location of the allocated StockItem.""" + locations = location.get_descendants(include_self=True) + return queryset.filter(item__location__in=locations) + + +class TransferOrderAllocationMixin: + """Mixin class for TransferOrderAllocation endpoints.""" + + queryset = models.TransferOrderAllocation.objects.all() + serializer_class = serializers.TransferOrderAllocationSerializer + + def get_queryset(self, *args, **kwargs): + """Annotate the queryset for this endpoint.""" + queryset = super().get_queryset(*args, **kwargs) + + queryset = queryset.prefetch_related( + 'item', + 'item__sales_order', + 'item__part', + 'line__part', + 'item__location', + 'line__order', + 'line__order__responsible', + 'line__order__project_code', + 'line__order__project_code__responsible', + ).select_related('line__part__pricing_data', 'item__part__pricing_data') + + return queryset + + +class TransferOrderAllocationOutputOptions(OutputConfiguration): + """Output options for the TransferOrderAllocation endpoint.""" + + OPTIONS = [ + InvenTreeOutputOption('part_detail'), + InvenTreeOutputOption('item_detail'), + InvenTreeOutputOption('order_detail'), + InvenTreeOutputOption('location_detail'), + ] + + +class TransferOrderAllocationList( + TransferOrderAllocationMixin, BulkUpdateMixin, OutputOptionsMixin, ListAPI +): + """API endpoint for listing TransferOrderAllocation objects.""" + + filterset_class = TransferOrderAllocationFilter + filter_backends = SEARCH_ORDER_FILTER + output_options = TransferOrderAllocationOutputOptions + + ordering_fields = [ + 'quantity', + 'part', + 'serial', + 'IPN', + 'batch', + 'location', + 'order', + ] + + ordering_field_aliases = { + 'IPN': 'item__part__IPN', + 'part': 'item__part__name', + 'serial': ['item__serial_int', 'item__serial'], + 'batch': 'item__batch', + 'location': 'item__location__name', + 'order': 'line__order__reference', + } + + search_fields = { + 'item__part__name', + 'item__part__IPN', + 'item__serial', + 'item__batch', + } + + +class TransferOrderAllocationDetail( + TransferOrderAllocationMixin, RetrieveUpdateDestroyAPI +): + """API endpoint for detail view of a TransferOrderAllocation object.""" + + +class TransferOrderLineItemFilter(LineItemFilter): + """Custom filters for TransferOrderLineItemList endpoint.""" + + class Meta: + """Metaclass options.""" + + model = models.TransferOrderLineItem + fields = [] + + order = rest_filters.ModelChoiceFilter( + queryset=models.TransferOrder.objects.all(), + field_name='order', + label=_('Order'), + ) + + def filter_include_variants(self, queryset, name, value): + """Filter by whether or not to include variants of the selected part. + + Note: + - This filter does nothing by itself, and requires the 'part' filter to be set. + - Refer to the 'filter_part' method for more information. + """ + return queryset + + part = rest_filters.ModelChoiceFilter( + queryset=Part.objects.all(), + field_name='part', + label=_('Part'), + method='filter_part', + ) + + @extend_schema_field(OpenApiTypes.INT) + def filter_part(self, queryset, name, part): + """Filter TransferOrderLineItem by selected 'part'. + + Note: + - If 'include_variants' is set to True, then all variants of the selected part will be included. + - Otherwise, just filter by the selected part. + """ + include_variants = str2bool(self.data.get('include_variants', False)) + + # Construct a queryset of parts to filter by + if include_variants: + parts = part.get_descendants(include_self=True) + else: + parts = Part.objects.filter(pk=part.pk) + + return queryset.filter(part__in=parts) + + allocated = rest_filters.BooleanFilter( + label=_('Allocated'), method='filter_allocated' + ) + + def filter_allocated(self, queryset, name, value): + """Filter by lines which are 'allocated'. + + A line is 'allocated' when allocated >= quantity + """ + q = Q(allocated__gte=F('quantity')) + + if str2bool(value): + return queryset.filter(q) + return queryset.exclude(q) + + completed = rest_filters.BooleanFilter( + label=_('Completed'), method='filter_completed' + ) + + def filter_completed(self, queryset, name, value): + """Filter by lines which are "completed". + + A line is 'completed' when transferred >= quantity + """ + q = Q(transferred__gte=F('quantity')) + + if str2bool(value): + return queryset.filter(q) + return queryset.exclude(q) + + order_complete = rest_filters.BooleanFilter( + label=_('Order Complete'), method='filter_order_complete' + ) + + def filter_order_complete(self, queryset, name, value): + """Filter by whether the order is 'complete' or not.""" + if str2bool(value): + return queryset.filter(order__status__in=TransferOrderStatusGroups.COMPLETE) + + return queryset.exclude(order__status__in=TransferOrderStatusGroups.COMPLETE) + + order_outstanding = rest_filters.BooleanFilter( + label=_('Order Outstanding'), method='filter_order_outstanding' + ) + + def filter_order_outstanding(self, queryset, name, value): + """Filter by whether the order is 'outstanding' or not.""" + if str2bool(value): + return queryset.filter(order__status__in=TransferOrderStatusGroups.OPEN) + + return queryset.exclude(order__status__in=TransferOrderStatusGroups.OPEN) + + +class TransferOrderLineItemMixin(SerializerContextMixin): + """Mixin class for TransferOrderLineItem endpoints.""" + + queryset = models.TransferOrderLineItem.objects.all() + serializer_class = serializers.TransferOrderLineItemSerializer + + def get_queryset(self, *args, **kwargs): + """Return annotated queryset for this endpoint.""" + queryset = super().get_queryset(*args, **kwargs) + + queryset = queryset.prefetch_related( + 'part', + 'allocations', + # 'allocations__transfer', + 'allocations__item__part', + 'allocations__item__location', + 'order', + ) + + queryset = serializers.TransferOrderLineItemSerializer.annotate_queryset( + queryset + ) + + return queryset + + +class TransferOrderLineItemOutputOptions(OutputConfiguration): + """Output options for the TransferOrderAllocation endpoint.""" + + OPTIONS = [ + InvenTreeOutputOption('part_detail'), + InvenTreeOutputOption('order_detail'), + ] + + +class TransferOrderLineItemList( + TransferOrderLineItemMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateAPI +): + """API endpoint for accessing a list of TransferOrderLineItem objects.""" + + filterset_class = TransferOrderLineItemFilter + + filter_backends = SEARCH_ORDER_FILTER + + output_options = TransferOrderLineItemOutputOptions + + ordering_fields = [ + 'order', + 'part', + 'part__name', + 'quantity', + 'allocated', + 'transferred', + 'reference', + 'target_date', + ] + + ordering_field_aliases = {'part': 'part__name', 'order': 'order__reference'} + + search_fields = ['part__name', 'quantity', 'reference'] + + +class TransferOrderLineItemDetail( + TransferOrderLineItemMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI +): + """API endpoint for detail view of a TransferOrderLineItem object.""" + + output_options = TransferOrderLineItemOutputOptions + + class OrderCalendarExport(ICalFeed): """Calendar export for Purchase/Sales Orders. @@ -1796,6 +2356,8 @@ class OrderCalendarExport(ICalFeed): ordertype_title = _('Sales Order') elif obj['ordertype'] == 'return-order': ordertype_title = _('Return Order') + elif obj['ordertype'] == 'transfer-order': + ordertype_title = _('Transfer Order') else: ordertype_title = _('Unknown') @@ -1841,6 +2403,15 @@ class OrderCalendarExport(ICalFeed): ).filter(status__lt=ReturnOrderStatus.COMPLETE.value) else: outlist = models.ReturnOrder.objects.filter(target_date__isnull=False) + elif obj['ordertype'] == 'transfer-order': + if obj['include_completed'] is False: + # Do not include completed orders from list in this case + # Complete status = 30 + outlist = models.TransferOrder.objects.filter( + target_date__isnull=False + ).filter(status__lt=TransferOrderStatus.COMPLETE.value) + else: + outlist = models.TransferOrder.objects.filter(target_date__isnull=False) else: outlist = [] @@ -1852,7 +2423,12 @@ class OrderCalendarExport(ICalFeed): def item_description(self, item): """Set the event description.""" - return f'Company: {item.company.name}\nStatus: {item.get_status_display()}\nDescription: {item.description}' + if hasattr(item, 'company') and item.company: + return f'Company: {item.company.name}\nStatus: {item.get_status_display()}\nDescription: {item.description}' + else: + return ( + f'Status: {item.get_status_display()}\nDescription: {item.description}' + ) def item_start_datetime(self, item): """Set event start to target date. Goal is all-day event.""" @@ -2128,9 +2704,97 @@ order_api_urls = [ ), ]), ), + # API endpoints for transfer orders + path( + 'transfer-order/', + include([ + # Transfer Order detail endpoints + path( + '/', + include([ + path( + 'allocate/', + TransferOrderAllocate.as_view(), + name='api-transfer-order-allocate', + ), + path( + 'allocate-serials/', + TransferOrderAllocateSerials.as_view(), + name='api-transfer-order-allocate-serials', + ), + path( + 'cancel/', + TransferOrderCancel.as_view(), + name='api-transfer-order-cancel', + ), + path( + 'hold/', + TransferOrderHold.as_view(), + name='api-transfer-order-hold', + ), + path( + 'complete/', + TransferOrderComplete.as_view(), + name='api-transfer-order-complete', + ), + path( + 'issue/', + TransferOrderIssue.as_view(), + name='api-transfer-order-issue', + ), + meta_path(models.TransferOrder), + path( + '', + TransferOrderDetail.as_view(), + name='api-transfer-order-detail', + ), + ]), + ), + # Transfer Order list + path('', TransferOrderList.as_view(), name='api-transfer-order-list'), + ]), + ), + # API endpoints for transfer order line items + path( + 'transfer-order-line/', + include([ + path( + '/', + include([ + meta_path(models.TransferOrderLineItem), + path( + '', + TransferOrderLineItemDetail.as_view(), + name='api-transfer-order-line-detail', + ), + ]), + ), + path( + '', + TransferOrderLineItemList.as_view(), + name='api-transfer-order-line-list', + ), + ]), + ), + # API endpoints for sales order allocations + path( + 'transfer-order-allocation/', + include([ + path( + '/', + TransferOrderAllocationDetail.as_view(), + name='api-transfer-order-allocation-detail', + ), + path( + '', + TransferOrderAllocationList.as_view(), + name='api-transfer-order-allocation-list', + ), + ]), + ), # API endpoint for subscribing to ICS calendar of purchase/sales/return orders re_path( - r'^calendar/(?Ppurchase-order|sales-order|return-order)/calendar.ics', + r'^calendar/(?Ppurchase-order|sales-order|return-order|transfer-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar', ), diff --git a/src/backend/InvenTree/order/events.py b/src/backend/InvenTree/order/events.py index 0d67a3e11b..4f17e26e35 100644 --- a/src/backend/InvenTree/order/events.py +++ b/src/backend/InvenTree/order/events.py @@ -37,3 +37,12 @@ class ReturnOrderEvents(BaseEventEnum): COMPLETED = 'returnorder.completed' CANCELLED = 'returnorder.cancelled' HOLD = 'returnorder.hold' + + +class TransferOrderEvents(BaseEventEnum): + """Event enumeration for the PurchaseOrder models.""" + + ISSUED = 'transferorder.placed' + COMPLETED = 'transferorder.completed' + CANCELLED = 'transferorder.cancelled' + HOLD = 'transferorder.hold' diff --git a/src/backend/InvenTree/order/fixtures/transfer_order.yaml b/src/backend/InvenTree/order/fixtures/transfer_order.yaml new file mode 100644 index 0000000000..e4293d0f9a --- /dev/null +++ b/src/backend/InvenTree/order/fixtures/transfer_order.yaml @@ -0,0 +1,68 @@ +- model: order.transferorder + pk: 1 + fields: + reference: 'TO-123' + description: "One transfer order, please" + status: 10 # Pending + +- model: order.transferorder + pk: 2 + fields: + reference: 'TO-124' + description: "One transfer order, please" + status: 40 # Cancelled + +- model: order.transferorder + pk: 3 + fields: + reference: 'TO-125' + description: "One transfer order, please" + status: 25 # On Hold + +- model: order.transferorder + pk: 4 + fields: + reference: 'TO-126' + description: "One transfer order, please" + status: 20 # Issued + +- model: order.transferorder + pk: 5 + fields: + reference: 'TO-127' + description: "One transfer order, please" + status: 30 # Complete + + +# Line items for transfer orders +- model: order.transferorderlineitem + pk: 1 + fields: + order: 5 # the completed order + part: 10001 # blue chair + quantity: 1 + +- model: order.transferorderlineitem + pk: 2 + fields: + order: 4 # the issued order + part: 10001 # blue chair + quantity: 1 + transferred: 1 + +# Allocations for transfer orders +# an 'allocated' allocation +- model: order.transferorderallocation + pk: 1 + fields: + line: 1 # the line item on the completed order + item: 1 # stock item + quantity: 1 + +# a 'complete' allocation +- model: order.transferorderallocation + pk: 2 + fields: + line: 2 # the line item on the issued order + item: 500 # stock item for the blue chair + quantity: 1 diff --git a/src/backend/InvenTree/order/migrations/0115_purchaseorder_updated_at_returnorder_updated_at_and_more.py b/src/backend/InvenTree/order/migrations/0115_purchaseorder_updated_at_returnorder_updated_at_and_more.py new file mode 100644 index 0000000000..837e2a35e4 --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0115_purchaseorder_updated_at_returnorder_updated_at_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.11 on 2026-02-19 22:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0114_purchaseorderextraline_project_code_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="purchaseorder", + name="updated_at", + field=models.DateTimeField( + blank=True, + null=True, + help_text="Timestamp of last update", + verbose_name="Updated At", + ), + ), + migrations.AddField( + model_name="returnorder", + name="updated_at", + field=models.DateTimeField( + blank=True, + null=True, + help_text="Timestamp of last update", + verbose_name="Updated At", + ), + ), + migrations.AddField( + model_name="salesorder", + name="updated_at", + field=models.DateTimeField( + blank=True, + null=True, + help_text="Timestamp of last update", + verbose_name="Updated At", + ), + ), + ] diff --git a/src/backend/InvenTree/order/migrations/0116_purchaseorderextraline_line_and_more.py b/src/backend/InvenTree/order/migrations/0116_purchaseorderextraline_line_and_more.py new file mode 100644 index 0000000000..740c9382e2 --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0116_purchaseorderextraline_line_and_more.py @@ -0,0 +1,79 @@ +# Generated by Django 5.2.12 on 2026-04-08 03:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0115_purchaseorder_updated_at_returnorder_updated_at_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="purchaseorderextraline", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + migrations.AddField( + model_name="purchaseorderlineitem", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + migrations.AddField( + model_name="returnorderextraline", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + migrations.AddField( + model_name="returnorderlineitem", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + migrations.AddField( + model_name="salesorderextraline", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + migrations.AddField( + model_name="salesorderlineitem", + name="line", + field=models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ), + ] diff --git a/src/backend/InvenTree/order/migrations/0117_purchaseorderextraline_line_int_and_more.py b/src/backend/InvenTree/order/migrations/0117_purchaseorderextraline_line_int_and_more.py new file mode 100644 index 0000000000..5d166331fb --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0117_purchaseorderextraline_line_int_and_more.py @@ -0,0 +1,74 @@ +# Generated by Django 5.2.13 on 2026-05-07 04:10 + +from django.db import migrations, models + + +def add_integer_line_number(apps, schema_editor): + """Add integer line numbers to existing line items.""" + + for model in [ + apps.get_model('order', 'PurchaseOrderLineItem'), + apps.get_model('order', 'ReturnOrderLineItem'), + apps.get_model('order', 'SalesOrderLineItem'), + apps.get_model('order', 'PurchaseOrderExtraLine'), + apps.get_model('order', 'ReturnOrderExtraLine'), + apps.get_model('order', 'SalesOrderExtraLine'), + ]: + items = [] + + for item in model.objects.exclude(line__isnull=True).exclude(line=''): + # Attempt to convert the existing line number to an integer + try: + item.line_int = int(item.line) + items.append(item) + except (ValueError, TypeError): + pass + + if len(items) > 0: + print(f"- Updating {len(items)} line items for model {model._meta.model_name}") + model.objects.bulk_update(items, ['line_int'], batch_size=250) + + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0116_purchaseorderextraline_line_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="purchaseorderextraline", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="purchaseorderlineitem", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="returnorderextraline", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="returnorderlineitem", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="salesorderextraline", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="salesorderlineitem", + name="line_int", + field=models.IntegerField(default=0), + ), + migrations.RunPython( + code=add_integer_line_number, + reverse_code=migrations.RunPython.noop, + ), + ] diff --git a/src/backend/InvenTree/order/migrations/0118_transferorder.py b/src/backend/InvenTree/order/migrations/0118_transferorder.py new file mode 100644 index 0000000000..ddaf02c8c6 --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0118_transferorder.py @@ -0,0 +1,482 @@ +# Generated by Django 5.2.11 on 2026-02-27 22:00 + +import InvenTree.fields +import InvenTree.models +import django.core.validators +import django.db.models.deletion +import generic.states.fields +import generic.states.states +import generic.states.transition +import generic.states.validators +import order.status_codes +import order.validators +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("common", "0041_auto_20251203_1244"), + ("company", "0077_delete_manufacturerpartparameter"), + ("order", "0117_purchaseorderextraline_line_int_and_more"), + ("part", "0146_auto_20251203_1241"), + ("stock", "0116_alter_stockitem_link"), + ("users", "0005_owner_model"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="TransferOrder", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "metadata", + models.JSONField( + blank=True, + help_text="JSON metadata field, for use by external plugins", + null=True, + verbose_name="Plugin Metadata", + ), + ), + ("reference_int", models.BigIntegerField(default=0)), + ( + "notes", + InvenTree.fields.InvenTreeNotesField( + blank=True, + help_text="Markdown notes (optional)", + max_length=50000, + null=True, + verbose_name="Notes", + ), + ), + ( + "barcode_data", + models.CharField( + blank=True, + help_text="Third party barcode data", + max_length=500, + verbose_name="Barcode Data", + ), + ), + ( + "barcode_hash", + models.CharField( + blank=True, + help_text="Unique hash of barcode data", + max_length=128, + verbose_name="Barcode Hash", + ), + ), + ( + "description", + models.CharField( + blank=True, + help_text="Order description (optional)", + max_length=250, + verbose_name="Description", + ), + ), + ( + "link", + InvenTree.fields.InvenTreeURLField( + blank=True, + help_text="Link to external page", + max_length=2000, + verbose_name="Link", + ), + ), + ( + "start_date", + models.DateField( + blank=True, + help_text="Scheduled start date for this order", + null=True, + verbose_name="Start date", + ), + ), + ( + "target_date", + models.DateField( + blank=True, + help_text="Expected date for order delivery. Order will be overdue after this date.", + null=True, + verbose_name="Target Date", + ), + ), + ( + "creation_date", + models.DateField( + blank=True, null=True, verbose_name="Creation Date" + ), + ), + ( + "issue_date", + models.DateField( + blank=True, + help_text="Date order was issued", + null=True, + verbose_name="Issue Date", + ), + ), + ( + "reference", + models.CharField( + default=order.validators.generate_next_transfer_order_reference, + help_text="Transfer Order Reference", + max_length=64, + unique=True, + validators=[order.validators.validate_transfer_order_reference], + verbose_name="Reference", + ), + ), + ( + "consume", + models.BooleanField( + default=False, + help_text='Rather than transfer the stock to the destination, "consume" it, by removing transferred quantity from the allocated stock item', + verbose_name="Consume Stock", + ), + ), + ( + "complete_date", + models.DateField( + blank=True, + help_text="Date order was completed", + null=True, + verbose_name="Completion Date", + ), + ), + ( + "status_custom_key", + generic.states.fields.ExtraInvenTreeCustomStatusModelField( + blank=True, + default=None, + help_text="Additional status information for this item", + null=True, + validators=[ + generic.states.validators.CustomStatusCodeValidator( + status_class=order.status_codes.TransferOrderStatus + ) + ], + verbose_name="Custom status key", + ), + ), + ( + "status", + generic.states.fields.InvenTreeCustomStatusModelField( + choices=[ + (10, "Pending"), + (20, "Issued"), + (25, "On Hold"), + (30, "Complete"), + (40, "Cancelled"), + ], + default=10, + help_text="Transfer order status", + validators=[ + generic.states.validators.CustomStatusCodeValidator( + status_class=order.status_codes.TransferOrderStatus + ) + ], + verbose_name="Status", + ), + ), + ( + "address", + models.ForeignKey( + blank=True, + help_text="Company address for this order", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="company.address", + verbose_name="Address", + ), + ), + ( + "contact", + models.ForeignKey( + blank=True, + help_text="Point of contact for this order", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="company.contact", + verbose_name="Contact", + ), + ), + ( + "created_by", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + verbose_name="Created By", + ), + ), + ( + "destination", + models.ForeignKey( + blank=True, + help_text="Destination for transferred items", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="incoming_transfers", + to="stock.stocklocation", + verbose_name="Destination Location", + ), + ), + ( + "project_code", + models.ForeignKey( + blank=True, + help_text="Select project code for this order", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="common.projectcode", + verbose_name="Project Code", + ), + ), + ( + "responsible", + models.ForeignKey( + blank=True, + help_text="User or group responsible for this order", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="users.owner", + verbose_name="Responsible", + ), + ), + ( + "take_from", + models.ForeignKey( + blank=True, + help_text="Source for transferred items", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="sourcing_transfers", + to="stock.stocklocation", + verbose_name="Source Location", + ), + ), + ( + "updated_at", + models.DateTimeField( + blank=True, + help_text="Timestamp of last update", + null=True, + verbose_name="Updated At", + ), + ) + ], + options={ + "verbose_name": "Transfer Order", + }, + bases=( + generic.states.states.StatusCodeMixin, + generic.states.transition.StateTransitionMixin, + InvenTree.models.InvenTreeAttachmentMixin, + InvenTree.models.InvenTreePermissionCheckMixin, + InvenTree.models.ContentTypeMixin, + InvenTree.models.PluginValidationMixin, + models.Model, + ), + ), + migrations.CreateModel( + name="TransferOrderLineItem", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "metadata", + models.JSONField( + blank=True, + help_text="JSON metadata field, for use by external plugins", + null=True, + verbose_name="Plugin Metadata", + ), + ), + ( + "quantity", + InvenTree.fields.RoundingDecimalField( + decimal_places=5, + default=1, + help_text="Item quantity", + max_digits=15, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Quantity", + ), + ), + ( + "reference", + models.CharField( + blank=True, + help_text="Line item reference", + max_length=100, + verbose_name="Reference", + ), + ), + ( + "notes", + models.CharField( + blank=True, + help_text="Line item notes", + max_length=500, + verbose_name="Notes", + ), + ), + ( + "link", + InvenTree.fields.InvenTreeURLField( + blank=True, + help_text="Link to external page", + max_length=2000, + verbose_name="Link", + ), + ), + ( + "target_date", + models.DateField( + blank=True, + help_text="Target date for this line item (leave blank to use the target date from the order)", + null=True, + verbose_name="Target Date", + ), + ), + ( + "order", + models.ForeignKey( + help_text="Transfer Order", + on_delete=django.db.models.deletion.CASCADE, + related_name="lines", + to="order.transferorder", + verbose_name="Order", + ), + ), + ( + "part", + models.ForeignKey( + help_text="Part", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="transfer_order_line_items", + to="part.part", + verbose_name="Part", + ), + ), + ( + "project_code", + models.ForeignKey( + blank=True, + help_text="Select project code for this order", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="common.projectcode", + verbose_name="Project Code", + ), + ), + ( + "transferred", + InvenTree.fields.RoundingDecimalField( + decimal_places=5, + default=0, + help_text="transferred quantity", + max_digits=15, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="transferred", + ), + ), + ( + "line", + models.CharField( + blank=True, + default="", + help_text="Line number for this item (optional)", + max_length=20, + verbose_name="Line Number", + ), + ) + ], + options={ + "verbose_name": "Transfer Order Line Item", + }, + bases=( + InvenTree.models.ContentTypeMixin, + InvenTree.models.PluginValidationMixin, + models.Model, + ), + ), + migrations.CreateModel( + name="TransferOrderAllocation", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "quantity", + InvenTree.fields.RoundingDecimalField( + decimal_places=5, + default=1, + help_text="Enter stock allocation quantity", + max_digits=15, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Quantity", + ), + ), + ( + "item", + models.ForeignKey( + help_text="Select stock item to allocate", + limit_choices_to={ + "belongs_to": None, + "part__virtual": False, + "sales_order": None, + }, + on_delete=django.db.models.deletion.CASCADE, + related_name="transfer_order_allocations", + to="stock.stockitem", + verbose_name="Item", + ), + ), + ( + "line", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="allocations", + to="order.transferorderlineitem", + verbose_name="Line", + ), + ), + ], + options={ + "verbose_name": "Transfer Order Allocation", + }, + ), + ] diff --git a/src/backend/InvenTree/order/migrations/0119_transferorderlineitem_line_int.py b/src/backend/InvenTree/order/migrations/0119_transferorderlineitem_line_int.py new file mode 100644 index 0000000000..e9ad06975c --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0119_transferorderlineitem_line_int.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.13 on 2026-05-11 21:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0118_transferorder"), + ] + + operations = [ + migrations.AddField( + model_name="transferorderlineitem", + name="line_int", + field=models.IntegerField(default=0), + ), + ] diff --git a/src/backend/InvenTree/order/models.py b/src/backend/InvenTree/order/models.py index f34c0cb6dd..5973f4292b 100644 --- a/src/backend/InvenTree/order/models.py +++ b/src/backend/InvenTree/order/models.py @@ -1,7 +1,7 @@ """Order model definitions.""" from decimal import Decimal -from typing import Any, Optional +from typing import Any, Optional, TypedDict from django.contrib.auth.models import User from django.core.exceptions import ValidationError @@ -9,7 +9,7 @@ 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.functions import Coalesce -from django.db.models.signals import post_save +from django.db.models.signals import post_delete, post_save from django.dispatch.dispatcher import receiver from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -45,7 +45,12 @@ from InvenTree.fields import ( ) from InvenTree.helpers import decimal2string, pui_url from InvenTree.helpers_model import notify_responsible -from order.events import PurchaseOrderEvents, ReturnOrderEvents, SalesOrderEvents +from order.events import ( + PurchaseOrderEvents, + ReturnOrderEvents, + SalesOrderEvents, + TransferOrderEvents, +) from order.status_codes import ( PurchaseOrderStatus, PurchaseOrderStatusGroups, @@ -54,6 +59,8 @@ from order.status_codes import ( ReturnOrderStatusGroups, SalesOrderStatus, SalesOrderStatusGroups, + TransferOrderStatus, + TransferOrderStatusGroups, ) from part import models as PartModels from plugin.events import trigger_event @@ -179,7 +186,7 @@ class TotalPriceMixin(models.Model): return total -class BaseOrderReportContext(report.mixins.BaseReportContext): +class BaseOrderReportContext(report.mixins.BaseReportContext, TypedDict): """Base context for all order models. Attributes: @@ -199,7 +206,7 @@ class BaseOrderReportContext(report.mixins.BaseReportContext): title: str -class PurchaseOrderReportContext(report.mixins.BaseReportContext): +class PurchaseOrderReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the purchase order model. Attributes: @@ -221,7 +228,7 @@ class PurchaseOrderReportContext(report.mixins.BaseReportContext): supplier: Optional[Company] -class SalesOrderReportContext(report.mixins.BaseReportContext): +class SalesOrderReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the sales order model. Attributes: @@ -243,7 +250,7 @@ class SalesOrderReportContext(report.mixins.BaseReportContext): customer: Optional[Company] -class ReturnOrderReportContext(report.mixins.BaseReportContext): +class ReturnOrderReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the return order model. Attributes: @@ -265,6 +272,27 @@ class ReturnOrderReportContext(report.mixins.BaseReportContext): customer: Optional[Company] +class TransferOrderReportContext(report.mixins.BaseReportContext, TypedDict): + """Context for the transfer order model. + + Attributes: + description: The description field of the TransferOrder + reference: The reference field of the TransferOrder + title: The title (string representation) of the TransferOrder + lines: Query set of all line items associated with the TransferOrder + order: The TransferOrder instance itself + """ + + description: str + reference: str + title: str + lines: report.mixins.QuerySet['TransferOrderLineItem'] + order: 'TransferOrder' + take_from: 'stock.models.StockLocation' + destination: 'stock.models.StockLocation' + consume: bool + + class Order( StatusCodeMixin, StateTransitionMixin, @@ -331,6 +359,8 @@ class Order( if not self.creation_date: self.creation_date = InvenTree.helpers.current_date() + self.updated_at = InvenTree.helpers.current_time() + super().save(*args, **kwargs) def check_locked(self, db: bool = False) -> bool: @@ -372,11 +402,16 @@ class Order( }) # Check that the referenced 'contact' matches the correct 'company' - if self.company and self.contact: - if self.contact.company != self.company: - raise ValidationError({ - 'contact': _('Contact does not match selected company') - }) + if ( + hasattr(self, 'company') + and hasattr(self, 'contact') + and self.company + and self.contact + and (self.contact.company != self.company) + ): + raise ValidationError({ + 'contact': _('Contact does not match selected company') + }) # Target date should be *after* the start date if self.start_date and self.target_date and self.start_date > self.target_date: @@ -386,11 +421,15 @@ class Order( }) # Check that the referenced 'address' matches the correct 'company' - if self.company and self.address: - if self.address.company != self.company: - raise ValidationError({ - 'address': _('Address does not match selected company') - }) + if ( + hasattr(self, 'company') + and self.company + and self.address + and (self.address.company != self.company) + ): + raise ValidationError({ + 'address': _('Address does not match selected company') + }) def clean_line_item(self, line): """Clean a line item for this order. @@ -406,7 +445,9 @@ class Order( """Generate context data for the reporting interface.""" return { 'description': self.description, - 'extra_lines': self.extra_lines, + 'extra_lines': getattr( + self, 'extra_lines', None + ), # Transfer Order doesn't have extra lines 'lines': self.lines, 'order': self, 'reference': self.reference, @@ -498,6 +539,13 @@ class Order( help_text=_('Date order was issued'), ) + updated_at = models.DateTimeField( + null=True, + blank=True, + verbose_name=_('Updated At'), + help_text=_('Timestamp of last update'), + ) + responsible = models.ForeignKey( UserModels.Owner, on_delete=models.SET_NULL, @@ -528,6 +576,19 @@ class Order( related_name='+', ) + @property + def company(self): + """Return 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.""" + return self.address or self.company.primary_address + @classmethod def get_status_class(cls): """Return the enumeration class which represents the 'status' field for this model.""" @@ -561,7 +622,9 @@ class PurchaseOrder(TotalPriceMixin, Order): def report_context(self) -> PurchaseOrderReportContext: """Return report context data for this PurchaseOrder.""" - return {**super().report_context(), 'supplier': self.supplier} + return_ctx = super().report_context() + return_ctx.update({'supplier': self.supplier}) + return return_ctx def get_absolute_url(self) -> str: """Get the 'web' URL for this order.""" @@ -1027,6 +1090,29 @@ class PurchaseOrder(TotalPriceMixin, Order): base_part = supplier_part.part + # Update the line item quantity + line.received += quantity + line_items_to_update.append(line) + + # Extract optional serial numbers + serials = item.get('serials', None) + + if serials and type(serials) is list and len(serials) > 0: + serialize = True + else: + serialize = False + serials = [None] + + if base_part.virtual: + # Virtual parts are not received into stock, so skip the rest of the loop + + if serialize: + raise ValidationError( + _('Serial numbers cannot be assigned to virtual parts') + ) + + continue + stock_location = item.get('location', location) or line.get_destination() # Calculate the received quantity in base part units @@ -1041,15 +1127,6 @@ class PurchaseOrder(TotalPriceMixin, Order): else: purchase_price = None - # Extract optional serial numbers - serials = item.get('serials', None) - - if serials and type(serials) is list and len(serials) > 0: - serialize = True - else: - serialize = False - serials = [None] - # Construct dataset for creating a new StockItem instances stock_data = { 'part': supplier_part.part, @@ -1133,13 +1210,11 @@ class PurchaseOrder(TotalPriceMixin, Order): bulk_create_items.append(new_item) - # Update the line item quantity - line.received += quantity - line_items_to_update.append(line) - # Bulk create new stock items if len(bulk_create_items) > 0: - stock.models.StockItem.objects.bulk_create(bulk_create_items) + stock.models.StockItem.objects.bulk_create( + bulk_create_items, batch_size=250 + ) # Fetch them back again tree_ids = [item.tree_id for item in bulk_create_items] @@ -1166,7 +1241,9 @@ class PurchaseOrder(TotalPriceMixin, Order): ) # Bulk create new tracking entries for each item - stock.models.StockItemTracking.objects.bulk_create(tracking_entries) + stock.models.StockItemTracking.objects.bulk_create( + tracking_entries, batch_size=250 + ) # Update received quantity for each line item PurchaseOrderLineItem.objects.bulk_update(line_items_to_update, ['received']) @@ -1260,7 +1337,9 @@ class SalesOrder(TotalPriceMixin, Order): def report_context(self) -> SalesOrderReportContext: """Generate report context data for this SalesOrder.""" - return {**super().report_context(), 'customer': self.customer} + return_ctx = super().report_context() + return_ctx.update({'customer': self.customer}) + return return_ctx def get_absolute_url(self) -> str: """Get the 'web' URL for this order.""" @@ -1715,6 +1794,8 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel): Attributes: quantity: Number of items + line: The line number for this item (optional) + line_int: An integer line number for this item (optional - used for natural sorting) reference: Reference text (e.g. customer reference) for this line item project_code: Project code associated with this line item (optional) note: Annotation for the item @@ -1738,6 +1819,15 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel): update_order = kwargs.pop('update_order', True) + # Update the integer representation of the line number (for natural sorting) + if self.line: + try: + self.line_int = int(self.line) + except (TypeError, ValueError): + self.line_int = 0 + else: + self.line_int = 0 + super().save(*args, **kwargs) if update_order and self.order: self.order.save() @@ -1770,6 +1860,17 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel): if self.price: return self.quantity * self.price + line = models.CharField( + max_length=20, + blank=True, + default='', + null=False, + verbose_name=_('Line Number'), + help_text=_('Line number for this item (optional)'), + ) + + line_int = models.IntegerField(default=0, blank=False, null=False) + reference = models.CharField( max_length=100, blank=True, @@ -1864,12 +1965,14 @@ class PurchaseOrderLineItem(OrderLineItem): verbose_name = _('Purchase Order Line Item') - # Filter for determining if a particular PurchaseOrderLineItem is overdue - OVERDUE_FILTER = ( - Q(received__lt=F('quantity')) - & ~Q(target_date=None) - & Q(target_date__lt=InvenTree.helpers.current_date()) - ) + @classmethod + def get_overdue_filter(cls): + """Filter for determining if a particular PurchaseOrderLineItem is overdue.""" + return ( + Q(received__lt=F('quantity')) + & ~Q(target_date=None) + & Q(target_date__lt=InvenTree.helpers.current_date()) + ) @staticmethod def get_api_url() -> str: @@ -1891,13 +1994,16 @@ class PurchaseOrderLineItem(OrderLineItem): if self.part.supplier != self.order.supplier: raise ValidationError({'part': _('Supplier part must match supplier')}) + # Link to the base part + part = self.part.part + if self.build_order: if not self.build_order.external: raise ValidationError({ 'build_order': _('Build order must be marked as external') }) - if part := self.part.part: + if part: if not part.assembly: raise ValidationError({ 'build_order': _( @@ -1910,6 +2016,17 @@ class PurchaseOrderLineItem(OrderLineItem): 'build_order': _('Build order part must match line item part') }) + # Extra checks for external builds + if part and part.assembly and get_global_setting('BUILDORDER_EXTERNAL_BUILDS'): + if not self.build_order and get_global_setting( + 'BUILDORDER_EXTERNAL_REQUIRED' + ): + raise ValidationError({ + 'build_order': _( + 'An external build order is required for assembly parts' + ) + }) + def __str__(self): """Render a string representation of a PurchaseOrderLineItem instance.""" return '{n} x {part} - {po}'.format( @@ -2068,12 +2185,14 @@ class SalesOrderLineItem(OrderLineItem): verbose_name = _('Sales Order Line Item') - # Filter for determining if a particular SalesOrderLineItem is overdue - OVERDUE_FILTER = ( - Q(shipped__lt=F('quantity')) - & ~Q(target_date=None) - & Q(target_date__lt=InvenTree.helpers.current_date()) - ) + @classmethod + def get_overdue_filter(cls): + """Filter for determining if a particular SalesOrderLineItem is overdue.""" + return ( + Q(shipped__lt=F('quantity')) + & ~Q(target_date=None) + & Q(target_date__lt=InvenTree.helpers.current_date()) + ) @staticmethod def get_api_url(): @@ -2184,7 +2303,7 @@ class SalesOrderLineItem(OrderLineItem): return self.shipped >= self.quantity -class SalesOrderShipmentReportContext(report.mixins.BaseReportContext): +class SalesOrderShipmentReportContext(report.mixins.BaseReportContext, TypedDict): """Context for the SalesOrderShipment model. Attributes: @@ -2207,6 +2326,7 @@ class SalesOrderShipmentReportContext(report.mixins.BaseReportContext): class SalesOrderShipment( + InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNotesMixin, @@ -2351,9 +2471,16 @@ class SalesOrderShipment( def address(self) -> Address: """Return the shipping address for this shipment. - If no specific shipment address is assigned, return the address from the order. + Lookup priority: + - Specific address assigned to this shipment + - Address assigned to the order + - Primary address of the customer """ - return self.shipment_address or self.order.address + return ( + self.shipment_address + or self.order.address + or self.order.customer.primary_address + ) def is_checked(self) -> bool: """Return True if this shipment has been checked.""" @@ -2405,54 +2532,45 @@ class SalesOrderShipment( 1. Update any stock items associated with this shipment 2. Update the "shipped" quantity of all associated line items 3. Set the "shipment_date" to now + + Arguments: + user: The user who is completing this shipment + + Returns: + task_id: The ID of the background task which is processing this shipment """ import order.tasks # Check if the shipment can be completed (throw error if not) self.check_can_complete() - # Update the "shipment" date - self.shipment_date = kwargs.get( - 'shipment_date', InvenTree.helpers.current_date() - ) - self.shipped_by = user - - # Was a tracking number provided? - tracking_number = kwargs.get('tracking_number') - - if tracking_number is not None: + if tracking_number := kwargs.get('tracking_number'): self.tracking_number = tracking_number - # Was an invoice number provided? - invoice_number = kwargs.get('invoice_number') - - if invoice_number is not None: + if invoice_number := kwargs.get('invoice_number'): self.invoice_number = invoice_number - # Was a link provided? - link = kwargs.get('link') - - if link is not None: + if link := kwargs.get('link'): self.link = link - # Was a delivery date provided? - delivery_date = kwargs.get('delivery_date') - - if delivery_date is not None: - self.delivery_date = delivery_date - self.save() + # Extract shipment date and delivery date from kwargs (if provided) + shipment_date = kwargs.get('shipment_date', InvenTree.helpers.current_date()) + delivery_date = kwargs.get('delivery_date') + # Offload the "completion" of each line item to the background worker # This may take some time, and we don't want to block the main thread - InvenTree.tasks.offload_task( + task_id = InvenTree.tasks.offload_task( order.tasks.complete_sales_order_shipment, - shipment_id=self.pk, - user_id=user.pk if user else None, + self.pk, + user.pk if user else None, + shipment_date, + delivery_date=delivery_date, group='sales_order', ) - trigger_event(SalesOrderEvents.SHIPMENT_COMPLETE, id=self.pk) + return task_id class SalesOrderExtraLine(OrderExtraLine): @@ -2658,7 +2776,9 @@ class ReturnOrder(TotalPriceMixin, Order): def report_context(self) -> ReturnOrderReportContext: """Generate report context data for this ReturnOrder.""" - return {**super().report_context(), 'customer': self.customer} + return_ctx = super().report_context() + return_ctx.update({'customer': self.customer}) + return return_ctx def get_absolute_url(self): """Get the 'web' URL for this order.""" @@ -3072,3 +3192,675 @@ class ReturnOrderExtraLine(OrderExtraLine): verbose_name=_('Order'), help_text=_('Return Order'), ) + + +class TransferOrder(Order): + """A Transfer Order represents a request to transfer stock from one location to another. It provides a place to queue and review changes before execution. + + Attributes: + take_from: The stock location to source items from (or null to ) + destination: The stock location to move items to + consume: Rather than move the stock, "consume" it. Helpful if you want to queue up removing stock from inventory + """ + + # Global setting for specifying reference pattern + REFERENCE_PATTERN_SETTING = 'TRANSFERORDER_REFERENCE_PATTERN' + REQUIRE_RESPONSIBLE_SETTING = 'TRANSFERORDER_REQUIRE_RESPONSIBLE' + STATUS_CLASS = TransferOrderStatus + # UNLOCK_SETTING = 'TRANSFERORDER_EDIT_COMPLETED_ORDERS' + + class Meta: + """Model meta options.""" + + verbose_name = _('Transfer Order') + + def report_context(self) -> TransferOrderReportContext: + """Return report context data for this TransferOrder.""" + return { + **super().report_context(), + 'take_from': self.take_from, + 'destination': self.destination, + 'consume': self.consume, + } + + def get_absolute_url(self) -> str: + """Get the 'web' URL for this order.""" + return pui_url(f'/stock/transfer-order/{self.pk}') + + @staticmethod + def get_api_url() -> str: + """Return the API URL associated with the TransferOrder model.""" + return reverse('api-transfer-order-list') + + @classmethod + def get_status_class(cls): + """Return the TransferOrderStatus class.""" + return TransferOrderStatusGroups + + @classmethod + def api_defaults(cls, request=None): + """Return default values for this model when issuing an API OPTIONS request.""" + defaults = { + 'reference': order.validators.generate_next_transfer_order_reference() + } + + return defaults + + @classmethod + def barcode_model_type_code(cls): + """Return the associated barcode model type code for this model.""" + return 'TO' + + def subscribed_users(self) -> list[User]: + """Return a list of users subscribed to this TransferOrder. + + By this, we mean users to are interested in any of the parts associated with this order. + """ + subscribed_users = set() + + for line in self.lines.all(): + if line.part: + # Add the part to the list of subscribed users + for user in line.part.get_subscribers(): + subscribed_users.add(user) + + return list(subscribed_users) + + def clean_line_item(self, line): + """Clean a line item for this PurchaseOrder.""" + super().clean_line_item(line) + line.transferred = 0 + + def __str__(self): + """Render a string representation of this TransferOrder.""" + return f'{self.reference} - {self.take_from.name if self.take_from else _("deleted")} --> {self.destination.name if self.destination else _("deleted")}' + + reference = models.CharField( + unique=True, + max_length=64, + blank=False, + help_text=_('Transfer Order Reference'), + verbose_name=_('Reference'), + default=order.validators.generate_next_transfer_order_reference, + validators=[order.validators.validate_transfer_order_reference], + ) + + status = InvenTreeCustomStatusModelField( + default=TransferOrderStatus.PENDING.value, + choices=TransferOrderStatus.items(), + status_class=TransferOrderStatus, + verbose_name=_('Status'), + help_text=_('Transfer order status'), + ) + + @property + def status_text(self): + """Return the text representation of the status field.""" + return TransferOrderStatus.text(self.status) + + take_from = models.ForeignKey( + 'stock.StockLocation', + verbose_name=_('Source Location'), + on_delete=models.SET_NULL, + related_name='sourcing_transfers', + blank=True, + null=True, + help_text=_('Source for transferred items'), + ) + + destination = models.ForeignKey( + 'stock.StockLocation', + verbose_name=_('Destination Location'), + on_delete=models.SET_NULL, + related_name='incoming_transfers', + blank=True, + null=True, + help_text=_('Destination for transferred items'), + ) + + consume = models.BooleanField( + default=False, + verbose_name=_('Consume Stock'), + help_text=_( + 'Rather than transfer the stock to the destination, "consume" it, by removing transferred quantity from the allocated stock item' + ), + ) + + complete_date = models.DateField( + blank=True, + null=True, + verbose_name=_('Completion Date'), + help_text=_('Date order was completed'), + ) + + @property + def company(self) -> None: + """Required accessor helper for Order base class.""" + return None + + @property + def is_pending(self) -> bool: + """Return True if the TransferOrder is 'pending'.""" + return self.status == TransferOrderStatus.PENDING.value + + @property + def is_open(self) -> bool: + """Return True if the TransferOrder is 'open'.""" + return self.status in TransferOrderStatusGroups.OPEN + + @property + def stock_allocations(self) -> QuerySet: + """Return a queryset containing all allocations for this order.""" + return TransferOrderAllocation.objects.filter( + line__in=[line.pk for line in self.lines.all()] + ) + + def is_fully_allocated(self) -> bool: + """Return True if all line items are fully allocated.""" + return all(line.is_fully_allocated() for line in self.lines.all()) + + def is_overallocated(self) -> bool: + """Return true if any lines in the order are over-allocated.""" + return any(line.is_overallocated() for line in self.lines.all()) + + def is_completed(self) -> bool: + """Check if this order is "transferred" (all line items transferred).""" + return all(line.is_completed() for line in self.lines.all()) + + def can_complete( + self, raise_error: bool = False, allow_incomplete_lines: bool = False + ) -> bool: + """Test if this TransferOrder can be completed.""" + try: + if self.status == TransferOrderStatus.COMPLETE.value: + raise ValidationError(_('Order is already complete')) + + if self.status == TransferOrderStatus.CANCELLED.value: + raise ValidationError(_('Order is already cancelled')) + + if not self.consume and not self.destination: + raise ValidationError( + _('Order cannot be completed until a destination location is set') + ) + + if not (self.is_fully_allocated() or allow_incomplete_lines): + raise ValidationError( + _('Order cannot be completed until it is fully allocated') + ) + except ValidationError as e: + if raise_error: + raise e + else: + return False + + return True + + @property + def can_issue(self) -> bool: + """Return True if this order can be issued.""" + return self.status in [ + TransferOrderStatus.PENDING.value, + TransferOrderStatus.ON_HOLD.value, + ] + + @transaction.atomic + def issue_order(self): + """Attempt to transition to PLACED status.""" + return self.handle_transition( + self.status, TransferOrderStatus.ISSUED.value, self, self._action_issue + ) + + # 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 + 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, + ] + + 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 + 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 + ) + + @transaction.atomic + def cancel_order(self): + """Attempt to transition to CANCELLED status.""" + return self.handle_transition( + self.status, TransferOrderStatus.CANCELLED.value, self, self._action_cancel + ) + + @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) + """ + 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, + exclude=self.created_by, + content=InvenTreeNotificationBodies.OrderCanceled, + extra_users=self.subscribed_users(), + ) + + # endregion + + @property + def line_count(self) -> int: + """Return the total number of lines associated with this order.""" + return self.lines.count() + + def completed_line_items(self) -> QuerySet: + """Return a queryset of the completed line items for this order.""" + return self.lines.filter(transferred__gte=F('quantity')) + + def pending_line_items(self) -> QuerySet: + """Return a queryset of the pending line items for this order.""" + return self.lines.filter(transferred__lt=F('quantity')) + + @property + def completed_line_count(self) -> int: + """Return the number of completed lines for this order.""" + return self.completed_line_items().count() + + @property + def pending_line_count(self) -> int: + """Return the number of pending (incomplete) lines associated with this order.""" + return self.pending_line_items().count() + + def allocations(self) -> QuerySet: + """Return a queryset of all allocations for this order.""" + return TransferOrderAllocation.objects.filter(line__order=self) + + +class TransferOrderLineItem(OrderLineItem): + """Model for a single LineItem in a TransferOrder. + + Attributes: + order: Link to the TransferOrder that this line item belongs to + part: Link to a Part object (may be null) + transferred: The number of items which have actually transferred against this line item + """ + + class Meta: + """Model meta options.""" + + verbose_name = _('Transfer Order Line Item') + + # Filter for determining if a particular TransferOrderLineItem is overdue + OVERDUE_FILTER = ( + Q(transferred__lt=F('quantity')) + & ~Q(target_date=None) + & Q(target_date__lt=InvenTree.helpers.current_date()) + ) + + @staticmethod + def get_api_url(): + """Return the API URL associated with the TransferOrderLineItem model.""" + return reverse('api-transfer-order-line-list') + + order = models.ForeignKey( + TransferOrder, + on_delete=models.CASCADE, + related_name='lines', + verbose_name=_('Order'), + help_text=_('Transfer Order'), + ) + + part = models.ForeignKey( + 'part.Part', + on_delete=models.SET_NULL, + related_name='transfer_order_line_items', + null=True, + verbose_name=_('Part'), + help_text=_('Part'), + # limit_choices_to={'salable': True}, + ) + + transferred = RoundingDecimalField( + verbose_name=_('transferred'), + help_text=_('transferred quantity'), + default=0, + max_digits=15, + decimal_places=5, + validators=[MinValueValidator(0)], + ) + + def allocated_quantity(self): + """Return the total stock quantity allocated to this LineItem. + + This is a summation of the quantity of each attached StockItem + """ + if not self.pk: + return 0 + + query = self.allocations.aggregate( + allocated=Coalesce(Sum('quantity'), Decimal(0)) + ) + + return query['allocated'] + + def is_fully_allocated(self) -> bool: + """Return True if this line item is fully allocated.""" + # If the linked part is "virtual", then we cannot allocate stock against it + if self.part and self.part.virtual: + return True + + return self.allocated_quantity() >= self.quantity + + def is_overallocated(self) -> bool: + """Return True if this line item is over allocated.""" + return self.allocated_quantity() > self.quantity + + def is_completed(self) -> bool: + """Return True if this line item is completed (has been fully shipped).""" + # A "virtual" part is always considered to be "completed" + if self.part and self.part.virtual: + return True + + return self.transferred >= self.quantity + + +class TransferOrderAllocation(models.Model): + """This model is used to 'allocate' stock items to a TransferOrder. Items that are "allocated" to a TransferOrder are not yet "attached" to the order, but they will be once the order is fulfilled. + + Attributes: + line: TransferOrderLineItem reference + item: StockItem reference + quantity: Quantity to take from the StockItem + """ + + class Meta: + """Model meta options.""" + + verbose_name = _('Transfer Order Allocation') + + @staticmethod + def get_api_url(): + """Return the API URL associated with the TransferOrderAllocation model.""" + return reverse('api-transfer-order-allocation-list') + + def clean(self): + """Validate the TransferOrderAllocation object. + + Executes: + - Cannot allocate stock to a line item without a part reference + - The referenced part must match the part associated with the line item + - Allocated quantity cannot exceed the quantity of the stock item + - Allocation quantity must be "1" if the StockItem is serialized + - Allocation quantity cannot be zero + """ + super().clean() + + errors = {} + + try: + if not self.item: + raise ValidationError({'item': _('Stock item has not been assigned')}) + except stock.models.StockItem.DoesNotExist: + raise ValidationError({'item': _('Stock item has not been assigned')}) + + try: + if self.line.part != self.item.part: + variants = self.line.part.get_descendants(include_self=True) + if self.line.part not in variants: + errors['item'] = _( + 'Cannot allocate stock item to a line with a different part' + ) + except PartModels.Part.DoesNotExist: + errors['line'] = _('Cannot allocate stock to a line without a part') + + if self.quantity > self.item.quantity: + errors['quantity'] = _('Allocation quantity cannot exceed stock quantity') + + # Ensure that we do not 'over allocate' a stock item + build_allocation_count = self.item.build_allocation_count() + sales_allocation_count = self.item.sales_order_allocation_count( + exclude_allocations={'pk': self.pk} + ) + + total_allocation = ( + build_allocation_count + sales_allocation_count + self.quantity + ) + + if total_allocation > self.item.quantity: + errors['quantity'] = _('Stock item is over-allocated') + + if self.quantity <= 0: + errors['quantity'] = _('Allocation quantity must be greater than zero') + + if self.item.serial and self.quantity != 1: + errors['quantity'] = _('Quantity must be 1 for serialized stock item') + + if len(errors) > 0: + raise ValidationError(errors) + + line = models.ForeignKey( + TransferOrderLineItem, + on_delete=models.CASCADE, + verbose_name=_('Line'), + related_name='allocations', + ) + + item = models.ForeignKey( + 'stock.StockItem', + on_delete=models.CASCADE, + related_name='transfer_order_allocations', + limit_choices_to={ + 'part__virtual': False, + 'belongs_to': None, + 'sales_order': None, + }, + verbose_name=_('Item'), + help_text=_('Select stock item to allocate'), + ) + + quantity = RoundingDecimalField( + max_digits=15, + decimal_places=5, + validators=[MinValueValidator(0)], + default=1, + verbose_name=_('Quantity'), + help_text=_('Enter stock allocation quantity'), + ) + + def get_location(self): + """Return the value of the location associated with this allocation.""" + return self.item.location.id if self.item.location else None + + def get_po(self): + """Return the PurchaseOrder associated with this allocation.""" + return self.item.purchase_order + + def complete_allocation(self, user): + """Complete this allocation (called when the parent TransferOrder is marked as "completed"). + + Executes: + - Determine if the referenced StockItem needs to be "split" (if allocated quantity != stock quantity) + - Move the StockItem to the new location + - Updates the transferred qty + - If order is marked as "consume", reduce quantity rather than move + """ + order: TransferOrder = self.line.order + self.item: stock.models.StockItem # for type hints + self.line: TransferOrderLineItem # for type hints + + # 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) + + 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 + # would be helpful here + self.item.take_stock( + quantity=self.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, + ) + self.save() + else: + # move item directly, we don't have to split + self.item.move( + location=order.destination, user=user, transferorder=order, notes='' + ) + + # Update the transferred qty + self.line.transferred += self.quantity + self.line.save() + + +def _touch_order_updated_at(instance): + """Bump updated_at on the parent order without triggering a full save.""" + if not InvenTree.ready.canAppAccessDatabase(allow_test=True): + return + instance.order.__class__.objects.filter(pk=instance.order_id).update( + updated_at=InvenTree.helpers.current_time() + ) + + +@receiver(post_save, sender=PurchaseOrderLineItem, dispatch_uid='po_lineitem_post_save') +@receiver( + post_delete, sender=PurchaseOrderLineItem, dispatch_uid='po_lineitem_post_delete' +) +@receiver( + post_save, sender=PurchaseOrderExtraLine, dispatch_uid='po_extraline_post_save' +) +@receiver( + post_delete, sender=PurchaseOrderExtraLine, dispatch_uid='po_extraline_post_delete' +) +@receiver(post_save, sender=SalesOrderLineItem, dispatch_uid='so_lineitem_post_save') +@receiver( + post_delete, sender=SalesOrderLineItem, dispatch_uid='so_lineitem_post_delete' +) +@receiver(post_save, sender=SalesOrderExtraLine, dispatch_uid='so_extraline_post_save') +@receiver( + post_delete, sender=SalesOrderExtraLine, dispatch_uid='so_extraline_post_delete' +) +@receiver(post_save, sender=ReturnOrderLineItem, dispatch_uid='ro_lineitem_post_save') +@receiver( + post_delete, sender=ReturnOrderLineItem, dispatch_uid='ro_lineitem_post_delete' +) +@receiver(post_save, sender=ReturnOrderExtraLine, dispatch_uid='ro_extraline_post_save') +@receiver( + post_delete, sender=ReturnOrderExtraLine, dispatch_uid='ro_extraline_post_delete' +) +@receiver( + post_save, + sender=TransferOrderLineItem, + dispatch_uid='transfer_order_lineitem_post_save', +) +@receiver( + post_delete, + sender=TransferOrderLineItem, + dispatch_uid='transfer_order_lineitem_post_delete', +) +def update_order_on_lineitem_change(sender, instance, **kwargs): + """Update parent order updated_at when any line item is saved or deleted.""" + _touch_order_updated_at(instance) diff --git a/src/backend/InvenTree/order/serializers.py b/src/backend/InvenTree/order/serializers.py index 5d0fd37d5b..c2d1b909ac 100644 --- a/src/backend/InvenTree/order/serializers.py +++ b/src/backend/InvenTree/order/serializers.py @@ -19,6 +19,7 @@ import order.models import part.filters as part_filters import stock.models import stock.serializers +from common.settings import get_global_setting from company.serializers import ( AddressBriefSerializer, CompanyBriefSerializer, @@ -27,13 +28,7 @@ from company.serializers import ( ) from generic.states.fields import InvenTreeCustomStatusSerializerMixin from importer.registry import register_importer -from InvenTree.helpers import ( - current_date, - extract_serial_numbers, - hash_barcode, - normalize, - str2bool, -) +from InvenTree.helpers import extract_serial_numbers, hash_barcode, normalize, str2bool from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.serializers import ( FilterableSerializerMixin, @@ -42,13 +37,14 @@ from InvenTree.serializers import ( InvenTreeModelSerializer, InvenTreeMoneySerializer, NotesFieldMixin, - enable_filter, + OptionalField, ) from order.status_codes import ( PurchaseOrderStatusGroups, ReturnOrderLineStatus, ReturnOrderStatus, SalesOrderStatusGroups, + TransferOrderStatusGroups, ) from part.serializers import PartBriefSerializer from stock.status_codes import StockStatus @@ -75,7 +71,7 @@ class DuplicateOrderSerializer(serializers.Serializer): class Meta: """Metaclass options.""" - fields = ['order_id', 'copy_lines', 'copy_extra_lines'] + 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') @@ -95,6 +91,13 @@ class DuplicateOrderSerializer(serializers.Serializer): 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 @@ -125,20 +128,28 @@ class AbstractOrderSerializer( reference = serializers.CharField(required=True) # Detail for point-of-contact field - contact_detail = enable_filter( - ContactSerializer( - source='contact', many=False, read_only=True, allow_null=True - ), - True, + contact_detail = OptionalField( + serializer_class=ContactSerializer, + serializer_kwargs={ + 'source': 'contact', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['contact'], ) # Detail for responsible field - responsible_detail = enable_filter( - OwnerSerializer( - source='responsible', read_only=True, allow_null=True, many=False - ), - True, + responsible_detail = OptionalField( + serializer_class=OwnerSerializer, + serializer_kwargs={ + 'source': 'responsible', + 'read_only': True, + 'allow_null': True, + 'many': False, + }, + default_include=True, prefetch_fields=['responsible'], ) @@ -146,11 +157,15 @@ class AbstractOrderSerializer( project_code_detail = common.filters.enable_project_code_filter() # Detail for address field - address_detail = enable_filter( - AddressBriefSerializer( - source='address', many=False, read_only=True, allow_null=True - ), - True, + address_detail = OptionalField( + serializer_class=AddressBriefSerializer, + serializer_kwargs={ + 'source': 'address', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['address'], ) @@ -242,6 +257,7 @@ class AbstractOrderSerializer( 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) try: copy_from = instance.__class__.objects.get(pk=order_id) @@ -260,6 +276,9 @@ class AbstractOrderSerializer( line.order = instance line.save() + if copy_parameters: + instance.copy_parameters_from(copy_from) + return instance @@ -271,6 +290,7 @@ class AbstractLineItemSerializer(FilterableSerializerMixin, serializers.Serializ """Construct a set of fields for this serializer.""" return [ 'pk', + 'line', 'link', 'notes', 'order', @@ -304,6 +324,7 @@ class AbstractExtraLineSerializer( """Construct a set of fields for this serializer.""" return [ 'pk', + 'line', 'description', 'link', 'notes', @@ -373,8 +394,14 @@ class PurchaseOrderSerializer( 'total_price', 'order_currency', 'destination', + 'updated_at', ]) - read_only_fields = ['issue_date', 'complete_date', 'creation_date'] + read_only_fields = [ + 'issue_date', + 'complete_date', + 'creation_date', + 'updated_at', + ] extra_kwargs = { 'supplier': {'required': True}, 'order_currency': {'required': False}, @@ -419,10 +446,14 @@ class PurchaseOrderSerializer( source='supplier.name', read_only=True, label=_('Supplier Name') ) - supplier_detail = enable_filter( - CompanyBriefSerializer( - source='supplier', many=False, read_only=True, allow_null=True - ), + supplier_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'supplier', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['supplier'], ) @@ -577,7 +608,7 @@ class PurchaseOrderLineItemSerializer( queryset = queryset.annotate( overdue=Case( When( - order.models.PurchaseOrderLineItem.OVERDUE_FILTER, + order.models.PurchaseOrderLineItem.get_overdue_filter(), then=Value(True, output_field=BooleanField()), ), default=Value(False, output_field=BooleanField()), @@ -616,19 +647,28 @@ class PurchaseOrderLineItemSerializer( total_price = serializers.FloatField(read_only=True) - part_detail = enable_filter( - PartBriefSerializer( - source='get_base_part', many=False, read_only=True, allow_null=True - ), - False, + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'get_base_part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='part_detail', ) - supplier_part_detail = enable_filter( - SupplierPartSerializer( - source='part', brief=True, many=False, read_only=True, allow_null=True - ), - False, + supplier_part_detail = OptionalField( + serializer_class=SupplierPartSerializer, + serializer_kwargs={ + 'source': 'part', + 'brief': True, + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='part_detail', ) @@ -642,11 +682,14 @@ class PurchaseOrderLineItemSerializer( default=False, ) - destination_detail = enable_filter( - stock.serializers.LocationBriefSerializer( - source='get_destination', read_only=True, allow_null=True - ), - True, + destination_detail = OptionalField( + serializer_class=stock.serializers.LocationBriefSerializer, + serializer_kwargs={ + 'source': 'get_destination', + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['destination', 'order__destination'], ) @@ -654,17 +697,26 @@ class PurchaseOrderLineItemSerializer( help_text=_('Purchase price currency') ) - order_detail = enable_filter( - PurchaseOrderSerializer( - source='order', read_only=True, allow_null=True, many=False - ) + order_detail = OptionalField( + serializer_class=PurchaseOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'read_only': True, + 'allow_null': True, + 'many': False, + }, + default_include=True, ) - build_order_detail = enable_filter( - build.serializers.BuildSerializer( - source='build_order', read_only=True, allow_null=True, many=False - ), - True, + build_order_detail = OptionalField( + serializer_class=build.serializers.BuildSerializer, + serializer_kwargs={ + 'source': 'build_order', + 'read_only': True, + 'allow_null': True, + 'many': False, + }, + default_include=True, prefetch_fields=[ 'build_order__responsible', 'build_order__issued_by', @@ -750,10 +802,14 @@ class PurchaseOrderExtraLineSerializer( model = order.models.PurchaseOrderExtraLine fields = AbstractExtraLineSerializer.extra_line_fields([]) - order_detail = enable_filter( - PurchaseOrderSerializer( - source='order', many=False, read_only=True, allow_null=True - ) + order_detail = OptionalField( + serializer_class=PurchaseOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) @@ -1026,8 +1082,9 @@ class SalesOrderSerializer( 'shipments_count', 'completed_shipments_count', 'allocated_lines', + 'updated_at', ]) - read_only_fields = ['status', 'creation_date', 'shipment_date'] + read_only_fields = ['status', 'creation_date', 'shipment_date', 'updated_at'] extra_kwargs = {'order_currency': {'required': False}} def skip_create_fields(self): @@ -1084,10 +1141,14 @@ class SalesOrderSerializer( return queryset - customer_detail = enable_filter( - CompanyBriefSerializer( - source='customer', many=False, read_only=True, allow_null=True - ), + customer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'customer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['customer'], ) @@ -1154,7 +1215,7 @@ class SalesOrderLineItemSerializer( overdue=Case( When( Q(order__status__in=SalesOrderStatusGroups.OPEN) - & order.models.SalesOrderLineItem.OVERDUE_FILTER, + & order.models.SalesOrderLineItem.get_overdue_filter(), then=Value(True, output_field=BooleanField()), ), default=Value(False, output_field=BooleanField()), @@ -1238,10 +1299,14 @@ class SalesOrderLineItemSerializer( return queryset - order_detail = enable_filter( - SalesOrderSerializer( - source='order', many=False, read_only=True, allow_null=True - ), + order_detail = OptionalField( + serializer_class=SalesOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=[ 'order__created_by', 'order__responsible', @@ -1251,15 +1316,25 @@ class SalesOrderLineItemSerializer( ], ) - part_detail = enable_filter( - PartBriefSerializer(source='part', many=False, read_only=True, allow_null=True), + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['part__pricing_data'], ) - customer_detail = enable_filter( - CompanyBriefSerializer( - source='order.customer', many=False, read_only=True, allow_null=True - ), + customer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'order.customer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['order__customer'], ) @@ -1285,7 +1360,10 @@ class SalesOrderLineItemSerializer( @register_importer() class SalesOrderShipmentSerializer( - FilterableSerializerMixin, NotesFieldMixin, InvenTreeModelSerializer + DataImportExportSerializerMixin, + FilterableSerializerMixin, + NotesFieldMixin, + InvenTreeModelSerializer, ): """Serializer for the SalesOrderShipment class.""" @@ -1308,6 +1386,7 @@ class SalesOrderShipmentSerializer( 'link', 'notes', # Extra detail fields + 'parameters', 'checked_by_detail', 'customer_detail', 'order_detail', @@ -1325,19 +1404,27 @@ class SalesOrderShipmentSerializer( read_only=True, allow_null=True, label=_('Allocated Items') ) - checked_by_detail = enable_filter( - UserSerializer( - source='checked_by', many=False, read_only=True, allow_null=True - ), - True, + checked_by_detail = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={ + 'source': 'checked_by', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['checked_by'], ) - order_detail = enable_filter( - SalesOrderSerializer( - source='order', read_only=True, allow_null=True, many=False - ), - True, + order_detail = OptionalField( + serializer_class=SalesOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=[ 'order', 'order__customer', @@ -1347,22 +1434,32 @@ class SalesOrderShipmentSerializer( ], ) - customer_detail = enable_filter( - CompanyBriefSerializer( - source='order.customer', many=False, read_only=True, allow_null=True - ), - False, + customer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'order.customer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['order__customer'], ) - shipment_address_detail = enable_filter( - AddressBriefSerializer( - source='shipment_address', many=False, read_only=True, allow_null=True - ), - True, + shipment_address_detail = OptionalField( + serializer_class=AddressBriefSerializer, + serializer_kwargs={ + 'source': 'shipment_address', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['shipment_address'], ) + parameters = common.filters.enable_parameters_filter() + class SalesOrderAllocationSerializer( FilterableSerializerMixin, InvenTreeModelSerializer @@ -1408,46 +1505,71 @@ class SalesOrderAllocationSerializer( ) # Extra detail fields - order_detail = enable_filter( - SalesOrderSerializer( - source='line.order', many=False, read_only=True, allow_null=True - ) - ) - part_detail = enable_filter( - PartBriefSerializer( - source='item.part', many=False, read_only=True, allow_null=True - ), - True, - ) - item_detail = enable_filter( - stock.serializers.StockItemSerializer( - source='item', - many=False, - read_only=True, - allow_null=True, - part_detail=False, - location_detail=False, - supplier_part_detail=False, - ), - True, - ) - location_detail = enable_filter( - stock.serializers.LocationBriefSerializer( - source='item.location', many=False, read_only=True, allow_null=True - ) - ) - customer_detail = enable_filter( - CompanyBriefSerializer( - source='line.order.customer', many=False, read_only=True, allow_null=True - ) + order_detail = OptionalField( + serializer_class=SalesOrderSerializer, + serializer_kwargs={ + 'source': 'line.order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) - shipment_detail = SalesOrderShipmentSerializer( - source='shipment', - order_detail=False, - many=False, - read_only=True, - allow_null=True, + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'item.part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, + ) + + item_detail = OptionalField( + serializer_class=stock.serializers.StockItemSerializer, + serializer_kwargs={ + 'source': 'item', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'part_detail': False, + 'location_detail': False, + 'supplier_part_detail': False, + }, + default_include=True, + ) + location_detail = OptionalField( + serializer_class=stock.serializers.LocationBriefSerializer, + serializer_kwargs={ + 'source': 'item.location', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + ) + + customer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'line.order.customer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + ) + + shipment_detail = OptionalField( + serializer_class=SalesOrderShipmentSerializer, + serializer_kwargs={ + 'source': 'shipment', + 'order_detail': False, + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, + prefetch_fields=['shipment'], ) @@ -1483,35 +1605,6 @@ class SalesOrderShipmentCompleteSerializer(serializers.ModelSerializer): return data - def save(self): - """Save the serializer to complete the SalesOrderShipment.""" - shipment = self.context.get('shipment', None) - - if not shipment: - return - - data = self.validated_data - - request = self.context.get('request') - user = request.user if request else None - - # Extract shipping date (defaults to today's date) - now = current_date() - shipment_date = data.get('shipment_date', now) - if shipment_date is None: - # Shipment date should not be None - check above only - # checks if shipment_date exists in data - shipment_date = now - - shipment.complete_shipment( - user, - tracking_number=data.get('tracking_number', shipment.tracking_number), - invoice_number=data.get('invoice_number', shipment.invoice_number), - link=data.get('link', shipment.link), - shipment_date=shipment_date, - delivery_date=data.get('delivery_date', shipment.delivery_date), - ) - class SalesOrderShipmentAllocationItemSerializer(serializers.Serializer): """A serializer for allocating a single stock-item against a SalesOrder shipment.""" @@ -1572,6 +1665,15 @@ class SalesOrderShipmentAllocationItemSerializer(serializers.Serializer): stock_item = data['stock_item'] quantity = data['quantity'] + if get_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'): + if ( + stock_item.hasRequiredTests() + and not stock_item.passedAllRequiredTests() + ): + raise ValidationError({ + 'stock_item': _('Stock item has not passed all required tests') + }) + if stock_item.serialized and quantity != 1: raise ValidationError({ 'quantity': _('Quantity must be 1 for serialized stock item') @@ -1762,6 +1864,14 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer): 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 @@ -1810,7 +1920,9 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer): ) with transaction.atomic(): - order.models.SalesOrderAllocation.objects.bulk_create(allocations) + order.models.SalesOrderAllocation.objects.bulk_create( + allocations, batch_size=250 + ) class SalesOrderShipmentAllocationSerializer(serializers.Serializer): @@ -1890,10 +2002,14 @@ class SalesOrderExtraLineSerializer( model = order.models.SalesOrderExtraLine fields = AbstractExtraLineSerializer.extra_line_fields([]) - order_detail = enable_filter( - SalesOrderSerializer( - source='order', many=False, read_only=True, allow_null=True - ) + order_detail = OptionalField( + serializer_class=SalesOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) @@ -1918,8 +2034,9 @@ class ReturnOrderSerializer( 'customer_reference', 'order_currency', 'total_price', + 'updated_at', ]) - read_only_fields = ['creation_date'] + read_only_fields = ['creation_date', 'updated_at'] def skip_create_fields(self): """Skip these fields when instantiating a new object.""" @@ -1950,10 +2067,14 @@ class ReturnOrderSerializer( return queryset - customer_detail = enable_filter( - CompanyBriefSerializer( - source='customer', many=False, read_only=True, allow_null=True - ), + customer_detail = OptionalField( + serializer_class=CompanyBriefSerializer, + serializer_kwargs={ + 'source': 'customer', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['customer'], ) @@ -2111,10 +2232,14 @@ class ReturnOrderLineItemSerializer( 'part_detail', ]) - order_detail = enable_filter( - ReturnOrderSerializer( - source='order', many=False, read_only=True, allow_null=True - ), + order_detail = OptionalField( + serializer_class=ReturnOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=[ 'order__created_by', 'order__responsible', @@ -2128,17 +2253,25 @@ class ReturnOrderLineItemSerializer( label=_('Quantity'), help_text=_('Quantity to return') ) - item_detail = enable_filter( - stock.serializers.StockItemSerializer( - source='item', many=False, read_only=True, allow_null=True - ), + item_detail = OptionalField( + serializer_class=stock.serializers.StockItemSerializer, + serializer_kwargs={ + 'source': 'item', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['item__supplier_part'], ) - part_detail = enable_filter( - PartBriefSerializer( - source='item.part', many=False, read_only=True, allow_null=True - ) + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'item.part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) price = InvenTreeMoneySerializer(allow_null=True) @@ -2157,8 +2290,631 @@ class ReturnOrderExtraLineSerializer( model = order.models.ReturnOrderExtraLine fields = AbstractExtraLineSerializer.extra_line_fields([]) - order_detail = enable_filter( - ReturnOrderSerializer( - source='order', many=False, read_only=True, allow_null=True - ) + order_detail = OptionalField( + serializer_class=ReturnOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) + + +@register_importer() +class TransferOrderSerializer( + NotesFieldMixin, + InvenTreeCustomStatusSerializerMixin, + AbstractOrderSerializer, + InvenTreeModelSerializer, +): + """Serializer for a TransferOrder object.""" + + class Meta: + """Metaclass options.""" + + model = order.models.TransferOrder + fields = AbstractOrderSerializer.order_fields([ + 'take_from', + 'take_from_detail', + 'destination', + 'destination_detail', + 'consume', + 'complete_date', + ]) + read_only_fields = ['creation_date'] + extra_kwargs = {} + + def skip_create_fields(self): + """Skip these fields when instantiating a new object.""" + fields = super().skip_create_fields() + + return [*fields, 'duplicate'] + + @staticmethod + def annotate_queryset(queryset): + """Add extra information to the queryset. + + - Number of line items in the TransferOrder + - Number of completed line items in the TransferOrder + - Overdue status of the TransferOrder + """ + queryset = AbstractOrderSerializer.annotate_queryset(queryset) + + queryset = queryset.annotate( + completed_lines=SubqueryCount( + 'lines', filter=Q(quantity__lte=F('transferred')) + ) + ) + + queryset = queryset.annotate( + overdue=Case( + When( + order.models.TransferOrder.overdue_filter(), + then=Value(True, output_field=BooleanField()), + ), + default=Value(False, output_field=BooleanField()), + ) + ) + + return queryset + + take_from_detail = OptionalField( + serializer_class=stock.serializers.LocationSerializer, + serializer_kwargs={ + 'source': 'take_from', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, + ) + + destination_detail = OptionalField( + serializer_class=stock.serializers.LocationSerializer, + serializer_kwargs={ + 'source': 'destination', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, + ) + + +class TransferOrderHoldSerializer(OrderAdjustSerializer): + """Serializer for placing a TransferOrder on hold.""" + + def save(self): + """Save the serializer to 'hold' the order.""" + self.order.hold_order() + + +class TransferOrderIssueSerializer(OrderAdjustSerializer): + """Serializer for issuing a transfer order.""" + + def save(self): + """Save the serializer to 'issue' the order.""" + self.order.issue_order() + + +class TransferOrderCancelSerializer(OrderAdjustSerializer): + """Serializer for cancelling a TransferOrder.""" + + def save(self): + """Save the serializer to 'cancel' the order.""" + if not self.order.can_cancel: + raise ValidationError(_('Order cannot be cancelled')) + + self.order.cancel_order() + + +class TransferOrderCompleteSerializer(OrderAdjustSerializer): + """Serializer for completing a transfer order.""" + + class Meta: + """Metaclass options.""" + + fields = ['accept_incomplete_allocation'] + + accept_incomplete_allocation = serializers.BooleanField( + label=_('Accept Incomplete Allocation'), + help_text=_('Allow order to complete with incomplete allocations'), + required=False, + default=False, + ) + + def validate_accept_incomplete_allocation(self, value): + """Check if the 'accept_incomplete_allocation' field is required.""" + order = self.context['order'] + + if not value and not order.is_fully_allocated(): + raise ValidationError(_('Order has incomplete allocations')) + + return value + + def get_context_data(self): + """Custom context information for this serializer.""" + order = self.context['order'] + + return {'is_complete': order.is_completed()} + + def validate(self, data): + """Custom validation for the serializer.""" + data = super().validate(data) + self.order.can_complete( + raise_error=True, + allow_incomplete_lines=str2bool( + data.get('accept_incomplete_allocation', False) + ), + ) + return data + + def save(self): + """Save the serializer to 'complete' the order.""" + request = self.context.get('request') + data = self.validated_data + user = request.user if request else None + + self.order.complete_order( + user=user, + allow_incomplete_lines=data.get('accept_incomplete_allocation', False), + ) + + +@register_importer() +class TransferOrderLineItemSerializer( + DataImportExportSerializerMixin, + AbstractLineItemSerializer, + InvenTreeModelSerializer, +): + """Serializer for a TransferOrderLineItem object.""" + + class Meta: + """Metaclass options.""" + + model = order.models.TransferOrderLineItem + fields = AbstractLineItemSerializer.line_fields([ + 'allocated', + 'overdue', + 'part', + 'part_detail', + 'transferred', + # Annotated fields for part stocking information + 'available_stock', + 'available_variant_stock', + 'building', + 'on_order', + # Filterable detail fields + ]) + + @staticmethod + def annotate_queryset(queryset): + """Add some extra annotations to this queryset. + + - "overdue" status (boolean field) + - "available_quantity" + - "building" + - "on_order" + """ + queryset = queryset.annotate( + overdue=Case( + When( + Q(order__status__in=TransferOrderStatusGroups.OPEN) + & order.models.TransferOrderLineItem.OVERDUE_FILTER, + then=Value(True, output_field=BooleanField()), + ), + default=Value(False, output_field=BooleanField()), + ) + ) + + # Annotate each line with the available stock quantity + # To do this, we need to look at the total stock and any allocations + queryset = queryset.alias( + total_stock=part_filters.annotate_total_stock(reference='part__'), + allocated_to_sales_orders=part_filters.annotate_sales_order_allocations( + reference='part__' + ), + allocated_to_build_orders=part_filters.annotate_build_order_allocations( + reference='part__' + ), + ) + + queryset = queryset.annotate( + available_stock=Greatest( + ExpressionWrapper( + F('total_stock') + - F('allocated_to_sales_orders') + - F('allocated_to_build_orders'), + output_field=models.DecimalField(), + ), + 0, + output_field=models.DecimalField(), + ) + ) + + # Add information about the quantity of parts currently on order + queryset = queryset.annotate( + on_order=part_filters.annotate_on_order_quantity(reference='part__') + ) + + # Add information about the quantity of parts currently in production + queryset = queryset.annotate( + building=part_filters.annotate_in_production_quantity(reference='part__') + ) + + # Annotate total 'allocated' stock quantity + queryset = queryset.annotate( + allocated=Coalesce( + SubquerySum('allocations__quantity'), + Decimal(0), + output_field=models.DecimalField(), + ) + ) + + return queryset + + order_detail = OptionalField( + serializer_class=TransferOrderSerializer, + serializer_kwargs={ + 'source': 'order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + prefetch_fields=[ + 'order__created_by', + 'order__responsible', + 'order__project_code', + ], + ) + + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + prefetch_fields=['part__pricing_data'], + ) + + # Annotated fields + overdue = serializers.BooleanField(read_only=True, allow_null=True) + available_stock = serializers.FloatField(read_only=True) + available_variant_stock = serializers.FloatField(read_only=True) + on_order = serializers.FloatField(label=_('On Order'), read_only=True) + building = serializers.FloatField(label=_('In Production'), read_only=True) + + quantity = InvenTreeDecimalField() + + allocated = serializers.FloatField(read_only=True) + + transferred = InvenTreeDecimalField(read_only=True) + + +class TransferOrderAllocationItemSerializer(serializers.Serializer): + """A serializer for allocating a single stock-item against a TransferOrder line item.""" + + class Meta: + """Metaclass options.""" + + fields = ['line_item', 'stock_item', 'quantity'] + + line_item = serializers.PrimaryKeyRelatedField( + queryset=order.models.TransferOrderLineItem.objects.all(), + many=False, + allow_null=False, + required=True, + label=_('Stock Item'), + ) + + def validate_line_item(self, line_item): + """Custom validation for the 'line_item' field. + + - Ensure the line_item is associated with the particular TransferOrder + """ + order = self.context['order'] + + # Ensure that the line item points to the correct order + if line_item.order != order: + raise ValidationError(_('Line item is not associated with this order')) + + return line_item + + stock_item = serializers.PrimaryKeyRelatedField( + queryset=stock.models.StockItem.objects.all(), + many=False, + allow_null=False, + required=True, + label=_('Stock Item'), + ) + + quantity = serializers.DecimalField( + max_digits=15, decimal_places=5, min_value=Decimal(0), required=True + ) + + def validate_quantity(self, quantity): + """Custom validation for the 'quantity' field.""" + if quantity <= 0: + raise ValidationError(_('Quantity must be positive')) + + return quantity + + def validate(self, data): + """Custom validation for the serializer. + + - Ensure that the quantity is 1 for serialized stock + - Quantity cannot exceed the available amount + """ + data = super().validate(data) + + stock_item = data['stock_item'] + quantity = data['quantity'] + + if stock_item.serialized and quantity != 1: + raise ValidationError({ + 'quantity': _('Quantity must be 1 for serialized stock item') + }) + + q = normalize(stock_item.unallocated_quantity()) + + if quantity > q: + raise ValidationError({'quantity': _(f'Available quantity ({q}) exceeded')}) + + return data + + +class TransferOrderLineItemAllocationSerializer(serializers.Serializer): + """DRF serializer for allocation of stock items against a transfer order line item.""" + + class Meta: + """Metaclass options.""" + + fields = ['items'] + + items = TransferOrderAllocationItemSerializer(many=True) + + def validate(self, data): + """Serializer validation.""" + data = super().validate(data) + + # Extract TransferOrder from serializer context + # order = self.context['order'] + + items = data.get('items', []) + + if len(items) == 0: + raise ValidationError(_('Allocation items must be provided')) + + return data + + def save(self): + """Perform the allocation of items against this order.""" + data = self.validated_data + + items = data['items'] + + with transaction.atomic(): + for entry in items: + # Create a new TransferOrderAllocation + allocation = order.models.TransferOrderAllocation( + line=entry.get('line_item'), + item=entry.get('stock_item'), + quantity=entry.get('quantity'), + ) + + allocation.full_clean() + allocation.save() + + +class TransferOrderAllocationSerializer( + FilterableSerializerMixin, InvenTreeModelSerializer +): + """Serializer for the TransferOrderAllocation model. + + This includes some fields from the related model objects. + """ + + class Meta: + """Metaclass options.""" + + model = order.models.TransferOrderAllocation + fields = [ + 'pk', + 'item', + 'quantity', + # Annotated read-only fields + 'line', + 'part', + 'order', + 'serial', + 'location', + # Extra detail fields + 'item_detail', + 'part_detail', + 'order_detail', + 'location_detail', + ] + read_only_fields = ['line', ''] + + part = serializers.PrimaryKeyRelatedField(source='item.part', read_only=True) + order = serializers.PrimaryKeyRelatedField( + source='line.order', many=False, read_only=True + ) + serial = serializers.CharField(source='get_serial', read_only=True, allow_null=True) + quantity = serializers.FloatField(read_only=False) + location = serializers.PrimaryKeyRelatedField( + source='item.location', many=False, read_only=True + ) + + # Extra detail fields + order_detail = OptionalField( + serializer_class=TransferOrderSerializer, + serializer_kwargs={ + 'source': 'line.order', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + ) + + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'item.part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + ) + + item_detail = OptionalField( + serializer_class=stock.serializers.StockItemSerializer, + serializer_kwargs={ + 'source': 'item', + 'many': False, + 'read_only': True, + 'allow_null': True, + 'part_detail': False, + 'location_detail': False, + 'supplier_part_detail': False, + }, + ) + + location_detail = OptionalField( + serializer_class=stock.serializers.LocationBriefSerializer, + serializer_kwargs={ + 'source': 'item.location', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + ) + + +class TransferOrderSerialAllocationSerializer(serializers.Serializer): + """DRF serializer for allocation of serial numbers against a transfer order.""" + + class Meta: + """Metaclass options.""" + + fields = ['line_item', 'quantity', 'serial_numbers'] + + line_item = serializers.PrimaryKeyRelatedField( + queryset=order.models.TransferOrderLineItem.objects.all(), + many=False, + required=True, + allow_null=False, + label=_('Line Item'), + ) + + def validate_line_item(self, line_item): + """Ensure that the line_item is valid.""" + order = self.context['order'] + + # Ensure that the line item points to the correct order + if line_item.order != order: + raise ValidationError(_('Line item is not associated with this order')) + + return line_item + + quantity = serializers.IntegerField( + min_value=1, required=True, allow_null=False, label=_('Quantity') + ) + + serial_numbers = serializers.CharField( + label=_('Serial Numbers'), + help_text=_('Enter serial numbers to allocate'), + required=True, + allow_blank=False, + ) + + 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) + + 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 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 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) diff --git a/src/backend/InvenTree/order/status_codes.py b/src/backend/InvenTree/order/status_codes.py index 7ec5756b92..d8893a1fa3 100644 --- a/src/backend/InvenTree/order/status_codes.py +++ b/src/backend/InvenTree/order/status_codes.py @@ -115,3 +115,30 @@ class ReturnOrderLineStatus(StatusCode): # Item is rejected REJECT = 60, _('Reject'), ColorEnum.danger + + +class TransferOrderStatus(StatusCode): + """Defines a set of status codes for a TransferOrder.""" + + # Order status codes + PENDING = 10, _('Pending'), ColorEnum.secondary # Order is pending (not yet issued) + ISSUED = 20, _('Issued'), ColorEnum.primary # Order has been issued + ON_HOLD = 25, _('On Hold'), ColorEnum.warning # Order is on hold + COMPLETE = 30, _('Complete'), ColorEnum.success # Order has been completed + CANCELLED = 40, _('Cancelled'), ColorEnum.danger # Order was cancelled + + +class TransferOrderStatusGroups: + """Groups for TransferOrderStatus codes.""" + + # Open orders + OPEN = [ + TransferOrderStatus.PENDING.value, + TransferOrderStatus.ON_HOLD.value, + TransferOrderStatus.ISSUED.value, + ] + + # Failed orders + FAILED = [TransferOrderStatus.CANCELLED.value] + + COMPLETE = [TransferOrderStatus.COMPLETE.value] diff --git a/src/backend/InvenTree/order/tasks.py b/src/backend/InvenTree/order/tasks.py index fea6891b34..d9065c2d20 100644 --- a/src/backend/InvenTree/order/tasks.py +++ b/src/backend/InvenTree/order/tasks.py @@ -1,6 +1,7 @@ """Background tasks for the 'order' app.""" from datetime import datetime, timedelta +from typing import Optional from django.contrib.auth.models import Group, User from django.db import transaction @@ -236,29 +237,39 @@ def check_overdue_return_orders(): @tracer.start_as_current_span('complete_sales_order_shipment') -def complete_sales_order_shipment(shipment_id: int, user_id: int) -> None: +def complete_sales_order_shipment( + shipment_id: int, + user_id: int, + shipment_date: str, + delivery_date: Optional[str] = None, +) -> None: """Complete allocations for a pending shipment against a SalesOrder. + Arguments: + shipment_id: The ID of the SalesOrderShipment object to complete + user_id: The ID of the user performing the completion action + shipment_date: The date that the shipment was completed (if None, then the current date is used) + delivery_date: The date that the shipment was delivered (optional) + At this stage, the shipment is assumed to be complete, and we need to perform the required "processing" tasks. """ - try: - shipment = order.models.SalesOrderShipment.objects.get(pk=shipment_id) - except Exception: - # Shipping object does not exist - logger.warning( - 'Failed to complete shipment - no matching SalesOrderShipment for ID <%s>', - shipment_id, - ) - return - - try: - user = User.objects.get(pk=user_id) - except Exception: - user = None + # 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) with transaction.atomic(): for allocation in shipment.allocations.all(): allocation.complete_allocation(user=user) + + # Once all allocations have been completed, we can mark the shipment as complete + shipment.shipment_date = shipment_date or datetime.now().date() + shipment.delivery_date = delivery_date + shipment.shipped_by = user + shipment.save() + + # Trigger event signalling that the shipment has been completed + trigger_event(SalesOrderEvents.SHIPMENT_COMPLETE, id=shipment.pk) diff --git a/src/backend/InvenTree/order/test_api.py b/src/backend/InvenTree/order/test_api.py index 9b3a4283de..2da8cd6115 100644 --- a/src/backend/InvenTree/order/test_api.py +++ b/src/backend/InvenTree/order/test_api.py @@ -27,6 +27,8 @@ from order.status_codes import ( ReturnOrderStatus, SalesOrderStatus, SalesOrderStatusGroups, + TransferOrderStatus, + TransferOrderStatusGroups, ) from part.models import Part from stock.models import StockItem, StockLocation @@ -46,9 +48,10 @@ class OrderTest(InvenTreeAPITestCase): 'stock', 'order', 'sales_order', + 'transfer_order', ] - roles = ['purchase_order.change', 'sales_order.change'] + roles = ['purchase_order.change', 'sales_order.change', 'transfer_order.change'] def filter(self, filters, count): """Test API filters.""" @@ -1336,6 +1339,47 @@ class PurchaseOrderReceiveTest(OrderTest): # Check that the expected number of stock items has been created self.assertEqual(n + 4, StockItem.objects.count()) + def test_virtual(self): + """Test receipt of "virtual" items (i.e. items which do not create a StockItem).""" + line = models.PurchaseOrderLineItem.objects.get(pk=1) + base_part = line.part.part + base_part.virtual = True + base_part.save() + + self.assertEqual(line.received, 0) + + N_ITEMS = base_part.stock_entries().count() + N_STOCK = base_part.get_stock_count() + + # Try with serial numbers (expect to fail) + data = { + 'items': [{'line_item': line.pk, 'quantity': 1, 'serial_numbers': '999'}], + 'location': 1, + } + + response = self.post(self.url, data, expected_code=400) + + self.assertIn( + 'Serial numbers cannot be assigned to virtual parts', + str(response.data['non_field_errors']), + ) + + # Try without serial numbers (expect to succeed) + data = { + 'items': [{'line_item': line.pk, 'quantity': line.quantity}], + 'location': 1, + } + + self.post(self.url, data, expected_code=201) + + # No new stock items should have been created + self.assertEqual(base_part.stock_entries().count(), N_ITEMS) + self.assertEqual(base_part.get_stock_count(), N_STOCK) + + # Check that the line item has been fully received + line.refresh_from_db() + self.assertEqual(line.received, line.quantity) + class SalesOrderTest(OrderTest): """Tests for the SalesOrder API.""" @@ -1574,6 +1618,65 @@ class SalesOrderTest(OrderTest): expected_code=201, ) + def test_so_duplicate(self): + """Test SalesOrder duplication via the API.""" + from common.models import Parameter, ParameterTemplate + + url = reverse('api-so-list') + + self.assignRole('sales_order.add') + + so = models.SalesOrder.objects.get(pk=1) + self.assertEqual(so.status, SalesOrderStatus.PENDING) + + # Add some parameters to the sales order + for idx in range(5): + template = ParameterTemplate.objects.create(name=f'Template {idx}') + + Parameter.objects.create( + template=template, + model_type=so.get_content_type(), + model_id=so.pk, + data=f'Value {idx}', + ) + + self.assertEqual(so.parameters.count(), 5) + + # Create a duplicate of this sales order + # We explicitly specify "copy_parameters" as False, so the duplicated sales order should not have any parameters + response = self.post( + url, + { + 'reference': 'SO-12345', + 'customer': so.customer.pk, + 'duplicate': {'order_id': so.pk, 'copy_parameters': False}, + }, + ) + + duplicate_id = response.data['pk'] + duplicate_so = models.SalesOrder.objects.get(pk=duplicate_id) + + self.assertEqual(duplicate_so.reference, 'SO-12345') + self.assertEqual(duplicate_so.customer, so.customer) + self.assertEqual(duplicate_so.parameters.count(), 0) + + # Duplicate again, with default values for the "duplicate" options (which should result in parameters being copied) + response = self.post( + url, + { + 'reference': 'SO-12346', + 'customer': so.customer.pk, + 'duplicate': {'order_id': so.pk}, + }, + ) + + duplicate_id = response.data['pk'] + duplicate_so = models.SalesOrder.objects.get(pk=duplicate_id) + + self.assertEqual(duplicate_so.reference, 'SO-12346') + self.assertEqual(duplicate_so.customer, so.customer) + self.assertEqual(duplicate_so.parameters.count(), 5) + def test_so_cancel(self): """Test API endpoint for cancelling a SalesOrder.""" so = models.SalesOrder.objects.get(pk=1) @@ -1931,7 +2034,11 @@ class SalesOrderLineItemTest(OrderTest): self.filter({'order': order_id, 'completed': 0}, 3) # Finally, mark this shipment as 'shipped' - self.post(reverse('api-so-shipment-ship', kwargs={'pk': shipment.pk}), {}) + self.post( + reverse('api-so-shipment-ship', kwargs={'pk': shipment.pk}), + {}, + expected_code=200, + ) # Filter by 'completed' status self.filter({'order': order_id, 'completed': 1}, 2) @@ -2219,7 +2326,7 @@ class SalesOrderAllocateTest(OrderTest): 'shipment_date': '2020-12-05', 'delivery_date': '2023-12-05', }, - expected_code=201, + expected_code=200, ) self.shipment.refresh_from_db() @@ -2300,6 +2407,43 @@ class SalesOrderAllocateTest(OrderTest): assert_subset=True, ) + def test_block_on_required_tests(self): + """Test the SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS setting.""" + from part.models import PartTestTemplate + + line = self.order.lines.first() + part = line.part + + # Make this a testable part + part.testable = True + part.save() + + # Create a required test + PartTestTemplate.objects.create( + part=part, test_name='A required test', required=True + ) + + data = { + 'items': [ + { + 'line_item': line.pk, + 'stock_item': part.stock_items.last().pk, + 'quantity': line.quantity, + } + ] + } + + set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', True) + + response = self.post(self.url, data, expected_code=400) + self.assertIn( + 'Stock item has not passed all required tests', str(response.data) + ) + + set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', False) + + response = self.post(self.url, data, expected_code=201) + class ReturnOrderTests(InvenTreeAPITestCase): """Unit tests for ReturnOrder API endpoints.""" @@ -2751,3 +2895,848 @@ class ReturnOrderLineItemTests(InvenTreeAPITestCase): line = models.ReturnOrderLineItem.objects.get(pk=1) self.assertEqual(float(line.price.amount), 15.75) + + +class TransferOrderTest(OrderTest): + """Tests for the TransferOrder API.""" + + LIST_URL = reverse('api-transfer-order-list') + + def test_transfer_order_list(self): + """Test the TransferOrder list API endpoint.""" + # all orders + self.filter({}, 5) + + # filter by outstanding + self.filter({'outstanding': True}, 3) + self.filter({'outstanding': False}, 2) + + # Filter by status + self.filter({'status': TransferOrderStatus.PENDING.value}, 1) + self.filter({'status': SalesOrderStatus.COMPLETE.value}, 1) + self.filter({'status': 99}, 0) # Invalid + + # Filter by "reference" + self.filter({'reference': 'TO-123'}, 1) + self.filter({'reference': 'TO-999'}, 0) + + # Filter by "assigned_to_me" + self.filter({'assigned_to_me': 1}, 0) + self.filter({'assigned_to_me': 0}, 5) + + def test_overdue(self): + """Test "overdue" status.""" + self.filter({'overdue': True}, 0) + self.filter({'overdue': False}, 5) + + # pick two orders that are still open (not cancelled or complete) + for pk in [1, 4]: + order = models.TransferOrder.objects.get(pk=pk) + order.target_date = datetime.now().date() - timedelta(days=10) + order.save() + + self.filter({'overdue': True}, 2) + self.filter({'overdue': False}, 3) + + def test_transfer_order_detail(self): + """Test the TransferOrder detail endpoint.""" + url = '/api/order/transfer-order/1/' + + response = self.get(url) + + data = response.data + + self.assertEqual(data['pk'], 1) + + def test_transfer_order_attachments(self): + """Test the list endpoint for the Transfer Order Attachments.""" + url = reverse('api-attachment-list') + + # Filter by 'transferorder' + self.get( + url, data={'model_type': 'transferorder', 'model_id': 1}, expected_code=200 + ) + + def test_transfer_order_operations(self): + """Test that we can create / edit and delete a TransferOrder via the API.""" + n = models.TransferOrder.objects.count() + + url = reverse('api-transfer-order-list') + + # Initially we do not have "add" permission for the TransferOrder model, + # so this POST request should return 403 (denied) + response = self.post( + url, + {'reference': 'TO-43245', 'description': 'Transfer order'}, + expected_code=403, + ) + + self.assignRole('transfer_order.add') + + # Now we should be able to create a TransferOrder via the API + response = self.post( + url, + {'reference': 'TO-12345', 'description': 'Transfer order'}, + expected_code=201, + ) + + # Check that the new order has been created + self.assertEqual(models.TransferOrder.objects.count(), n + 1) + + # Grab the PK for the newly created TransferOrder + pk = response.data['pk'] + + # Basic checks against the newly created TransferOrder + so = models.TransferOrder.objects.get(pk=pk) + self.assertEqual(so.reference, 'TO-12345') + self.assertEqual(so.created_by.username, 'testuser') + + # Try to create a TO with identical reference (should fail) + response = self.post( + url, + { + 'customer': 4, + 'reference': 'TO-12345', + 'description': 'Another transfer order', + }, + expected_code=400, + ) + + url = reverse('api-transfer-order-detail', kwargs={'pk': pk}) + + # Extract detail info for the TransferOrder + response = self.get(url) + self.assertEqual(response.data['reference'], 'TO-12345') + + # Try to alter (edit) the TransferOrder + # Initially try with an invalid reference field value + response = self.patch(url, {'reference': 'TO-12345-a'}, expected_code=400) + + response = self.patch(url, {'reference': 'TO-12346'}, expected_code=200) + + # Reference should have changed + self.assertEqual(response.data['reference'], 'TO-12346') + + # Now, let's try to delete this TransferOrder + # Initially, we do not have the required permission + response = self.delete(url, expected_code=403) + + self.assignRole('transfer_order.delete') + + response = self.delete(url, expected_code=204) + + # Check that the number of transfer orders has decreased + self.assertEqual(models.TransferOrder.objects.count(), n) + + # And the resource should no longer be available + response = self.get(url, expected_code=404) + + def test_transfer_order_create(self): + """Test that we can create a new TransferOrder via the API.""" + self.assignRole('transfer_order.add') + + url = reverse('api-transfer-order-list') + + # Will fail due to invalid reference field + response = self.post( + url, + {'reference': '1234566778', 'description': 'A test transfer order'}, + expected_code=400, + ) + + self.assertIn( + 'Reference must match required pattern', str(response.data['reference']) + ) + + self.post( + url, + {'reference': 'TO-12345', 'description': 'A better test transfer order'}, + expected_code=201, + ) + + def test_transfer_order_cancel(self): + """Test API endpoint for cancelling a TransferOrder.""" + to = models.TransferOrder.objects.get(pk=1) + + self.assertEqual(to.status, TransferOrderStatus.PENDING) + + url = reverse('api-transfer-order-cancel', kwargs={'pk': to.pk}) + + # Try to cancel, without permission + self.post(url, {}, expected_code=403) + + self.assignRole('transfer_order.add') + + self.post(url, {}, expected_code=201) + + 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) + + self.assertEqual(to.status, TransferOrderStatus.PENDING) + + url = reverse('api-transfer-order-hold', kwargs={'pk': to.pk}) + + # Try to hold, without permission + self.post(url, {}, expected_code=403) + + self.assignRole('transfer_order.add') + + self.post(url, {}, expected_code=201) + + to.refresh_from_db() + + self.assertEqual(to.status, TransferOrderStatus.ON_HOLD) + + def test_transfer_order_calendar(self): + """Test the calendar export endpoint.""" + # Create required transfer orders + self.assignRole('transfer_order.add') + + for i in range(1, 9): + self.post( + reverse('api-transfer-order-list'), + { + 'reference': f'TO-1100000{i}', + 'description': f'Calendar SO {i}', + 'target_date': f'2024-12-{i:02d}', + }, + expected_code=201, + ) + + # Cancel a few orders - these will not show in incomplete view below + for to in models.TransferOrder.objects.filter(target_date__isnull=False): + if to.reference in [ + 'TO-11000006', + 'TO-11000007', + 'TO-11000008', + 'TO-11000009', + ]: + self.post( + reverse('api-transfer-order-cancel', kwargs={'pk': to.pk}), + expected_code=201, + ) + + url = reverse('api-po-so-calendar', kwargs={'ordertype': 'transfer-order'}) + + # Test without completed orders + response = self.get(url, expected_code=200, format=None) + + number_orders = len( + models.TransferOrder.objects.filter(target_date__isnull=False).filter( + status__lt=TransferOrderStatus.COMPLETE.value + ) + ) + + # Transform content to a Calendar object + calendar = Calendar.from_ical(response.content) + n_events = 0 + # Count number of events in calendar + for component in calendar.walk(): + if component.name == 'VEVENT': + n_events += 1 + + self.assertGreaterEqual(n_events, 1) + self.assertEqual(number_orders, n_events) + + # Test with completed orders + response = self.get( + url, data={'include_completed': 'True'}, expected_code=200, format=None + ) + + number_orders_incl_complete = len( + models.TransferOrder.objects.filter(target_date__isnull=False) + ) + self.assertGreater(number_orders_incl_complete, number_orders) + + # Transform content to a Calendar object + calendar = Calendar.from_ical(response.content) + n_events = 0 + # Count number of events in calendar + for component in calendar.walk(): + if component.name == 'VEVENT': + n_events += 1 + + self.assertGreaterEqual(n_events, 1) + self.assertEqual(number_orders_incl_complete, n_events) + + def test_export(self): + """Test we can export the TransferOrder list.""" + n = models.TransferOrder.objects.count() + + # Check there are some sales orders + self.assertGreater(n, 0) + + # Download file, check we get a 200 response + for fmt in ['csv', 'xlsx', 'tsv']: + self.export_data( + reverse('api-transfer-order-list'), + export_format=fmt, + decode=fmt == 'csv', + expected_code=200, + expected_fn=r'InvenTree_TransferOrder_.+', + ) + + def test_transfer_order_complete(self): + """Tests for marking a TransferOrder as complete.""" + self.assignRole('transfer_order.add') + destination = StockLocation.objects.first() + # Let's create a TransferOrder + to = models.TransferOrder.objects.create( + reference='TO-12345', description='Test TO' + ) + + self.assertEqual(to.status, TransferOrderStatus.PENDING.value) + + # Create a line item + part = Part.objects.exclude(virtual=True).first() + + line = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + + # issue the order + url = reverse('api-transfer-order-issue', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.ISSUED.value) + + # Allocate some stock + item = StockItem.objects.create( + part=part, quantity=100, location=None, batch='transfer-order-test' + ) + short_allocation = models.TransferOrderAllocation.objects.create( + quantity=5, line=line, item=item + ) + + # attempt to complete the order, but fail because there are incomplete allocations + url = reverse('api-transfer-order-complete', kwargs={'pk': to.pk}) + response = self.post(url, {}, expected_code=400) + self.assertIn('has incomplete allocations', str(response.data)) + # allocate more stock + short_allocation.delete() + models.TransferOrderAllocation.objects.create(quantity=10, line=line, item=item) + + # attempt to complete the order, but fail because there is no destination yet + url = reverse('api-transfer-order-complete', kwargs={'pk': to.pk}) + response = self.post(url, {}, expected_code=400) + self.assertIn('until a destination location is set', str(response.data)) + # add destination + to.destination = destination + to.save() + + # Ok, now we should be able to "complete" the transfer via the API + 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) + self.assertIsNotNone(to.complete_date) + + # Now, let's try *again* (it should fail as the order is already complete) + response = self.post(url, {}, expected_code=400) + self.assertIn('Order is already complete', str(response.data)) + + # Now, we make sure the affected stock was transferred to the correct location + StockItem.objects.get( + part=part, quantity=10, batch='transfer-order-test', location=destination + ) + + def test_transfer_order_consume(self): + """Tests for marking a TransferOrder consume the stock it 'transfers'.""" + self.assignRole('transfer_order.add') + destination = StockLocation.objects.first() + # Let's create a TransferOrder + to = models.TransferOrder.objects.create( + reference='TO-12345', + description='Test TO', + consume=True, + destination=destination, + ) + + self.assertEqual(to.status, TransferOrderStatus.PENDING.value) + + # Create a line item + part = Part.objects.exclude(virtual=True).first() + + line = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + + # issue the order + url = reverse('api-transfer-order-issue', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.ISSUED.value) + + # Allocate some stock + item = StockItem.objects.create( + part=part, quantity=100, location=None, batch='transfer-order-test' + ) + models.TransferOrderAllocation.objects.create(quantity=10, line=line, item=item) + + # Ok, now we should be able to "complete" the transfer via the API + 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) + self.assertIsNotNone(to.complete_date) + + # Now, we make sure the affected stock was 'consumed', reducing available quantity + item.refresh_from_db() + self.assertEqual(item.quantity, 90) + + # and that it wasn't transferred to the destination + with self.assertRaises(StockItem.DoesNotExist): + StockItem.objects.get( + part=part, + quantity=10, + batch='transfer-order-test', + location=destination, + ) + + def test_output_options(self): + """Test the output options for the TransferOrder detail endpoint.""" + self.run_output_test( + reverse('api-transfer-order-detail', kwargs={'pk': 1}), + ['take_from_detail', 'destination_detail'], + ) + + +class TransferOrderLineItemTest(OrderTest): + """Tests for the TransferOrderLineItem API.""" + + LIST_URL = reverse('api-transfer-order-line-list') + + # adjust counts in asserts based on those created in setUpTestData + # plus those in fixtures + NUM_LINE_ITEMS_IN_FIXTURES = 2 + + @classmethod + def setUpTestData(cls): + """Init routine for this unit test class.""" + super().setUpTestData() + + # List of 'transferrable' parts + parts = Part.objects.exclude(virtual=True) + + lines = [] + + # Create a bunch of TransferOrderLineItems for each order + for idx, to in enumerate(models.TransferOrder.objects.all()): + for part in parts: + lines.append( + models.TransferOrderLineItem( + order=to, + part=part, + quantity=(idx + 1) * 5, + reference=f'Order {to.reference} - line {idx}', + ) + ) + + # Bulk create + models.TransferOrderLineItem.objects.bulk_create(lines) + + cls.url = reverse('api-transfer-order-line-list') + + def test_transfer_order_line_list(self): + """Test list endpoint.""" + response = self.get(self.url, {}, expected_code=200) + + n = models.TransferOrderLineItem.objects.count() + + # We should have received *all* lines + self.assertEqual(len(response.data), n) + + # List *all* lines, but paginate + response = self.get(self.url, {'limit': 5}, expected_code=200) + + self.assertEqual(response.data['count'], n) + self.assertEqual(len(response.data['results']), 5) + + n_orders = models.TransferOrder.objects.count() + n_parts = Part.objects.exclude(virtual=True).count() + + # List by part + # fixures add line items, avoid those here with [:3] for predictable counts + for part in Part.objects.exclude(virtual=True)[:3]: + response = self.get(self.url, {'part': part.pk, 'limit': 10}) + self.assertEqual(response.data['count'], n_orders) + + # List by order + # fixures add line items, avoid those here with [:3] for predictable counts + for order in models.TransferOrder.objects.all()[:3]: + response = self.get(self.url, {'order': order.pk, 'limit': 10}) + # count of line items equal to number of parts because + # we created a line item per part on each order in setUpTestData + self.assertEqual(response.data['count'], n_parts) + + # Filter by 'completed' status + self.filter({'completed': 1}, 1) + self.filter({'completed': 0}, n - 1) + + # Filter by 'allocated' status + self.filter({'allocated': 'true'}, 2) + self.filter({'allocated': 'false'}, n - 2) + + def test_transfer_order_line_allocated_filters(self): + """Test filtering by allocation status for a TransferOrderLineItem.""" + self.assignRole('transfer_order.add') + + destination = StockLocation.objects.first() + assert destination + + response = self.post( + reverse('api-transfer-order-list'), + { + 'reference': 'TO-12345', + 'description': 'Test Transfer Order', + 'destination': destination.pk, + }, + ) + + order_id = response.data['pk'] + order = models.TransferOrder.objects.get(pk=order_id) + + transfer_order_line_url = reverse('api-transfer-order-line-list') + + # Initially, there should be no line items against this order + response = self.get(transfer_order_line_url, {'order': order_id}) + + self.assertEqual(len(response.data), 0) + + parts = [25, 50, 100] + + # Let's create some new line items + for part_id in parts: + self.post( + transfer_order_line_url, + {'order': order_id, 'part': part_id, 'quantity': 10}, + ) + + # Should be three items now + response = self.get(transfer_order_line_url, {'order': order_id}) + + self.assertEqual(len(response.data), 3) + + for item in response.data: + # Check that the line item has been created + self.assertEqual(item['order'], order_id) + + # Check that the line quantities are correct + self.assertEqual(item['quantity'], 10) + self.assertEqual(item['allocated'], 0) + self.assertEqual(item['transferred'], 0) + + # Initial API filters should return no results + self.filter({'order': order_id, 'allocated': 1}, 0) + self.filter({'order': order_id, 'completed': 1}, 0) + + # issue the order + order_issue_url = reverse('api-transfer-order-issue', kwargs={'pk': order.pk}) + self.post(order_issue_url, {}, expected_code=201) + + # Next, allocate stock against 2 line items + for item in parts[:2]: + p = Part.objects.get(pk=item) + s = StockItem.objects.create(part=p, quantity=100) + l = models.TransferOrderLineItem.objects.filter(order=order, part=p).first() + assert l + + # Allocate against the API + self.post( + reverse('api-transfer-order-allocate', kwargs={'pk': order.pk}), + {'items': [{'line_item': l.pk, 'stock_item': s.pk, 'quantity': 10}]}, + ) + + # Filter by 'fully allocated' status + self.filter({'order': order_id, 'allocated': 1}, 2) + self.filter({'order': order_id, 'allocated': 0}, 1) + + self.filter({'order': order_id, 'completed': 1}, 0) + self.filter({'order': order_id, 'completed': 0}, 3) + + # Finally, attempt to transfer this line item + # we have incomplete allocations, so must specify arg + self.post( + reverse('api-transfer-order-complete', kwargs={'pk': order.pk}), + {'accept_incomplete_allocation': 'true'}, + ) + + # Filter by 'completed' status + self.filter({'order': order_id, 'completed': 1}, 2) + self.filter({'order': order_id, 'completed': 0}, 1) + + def test_output_options(self): + """Test the various output options for the TransferOrderLineItem detail endpoint.""" + self.run_output_test( + reverse('api-transfer-order-line-detail', kwargs={'pk': 1}), + ['part_detail', 'order_detail'], + ) + + +class TransferOrderDownloadTest(OrderTest): + """Unit tests for downloading TransferOrder data via the API endpoint.""" + + def test_download_fail(self): + """Test that downloading without the 'export' option fails.""" + url = reverse('api-transfer-order-list') + + response = self.export_data(url, export_plugin='no-plugin', expected_code=400) + self.assertIn('is not a valid choice', str(response['export_plugin'])) + + def test_download_xlsx(self): + """Test xlsx file download.""" + url = reverse('api-transfer-order-list') + + # Download .xls file + with self.export_data( + url, export_format='xlsx', expected_code=200, decode=False + ) as file: + self.assertIsInstance(file, io.BytesIO) + + def test_download_csv(self): + """Test that the list of transfer orders can be downloaded as a .csv file.""" + url = reverse('api-transfer-order-list') + + required_cols = [ + 'Line Items', + 'Completed Lines', + 'ID', + 'Reference', + 'Order Status', + 'Description', + 'Project Code', + 'Responsible', + 'Consume Stock', + ] + + excluded_cols = ['metadata'] + + # Download .xls file + with self.export_data(url, export_format='csv') as file: + data = self.process_csv( + file, + required_cols=required_cols, + excluded_cols=excluded_cols, + required_rows=models.TransferOrder.objects.count(), + ) + + for line in data: + order = models.TransferOrder.objects.get(pk=line['ID']) + + self.assertEqual(line['Description'], order.description) + self.assertEqual(line['Order Status'], str(order.status)) + + # Download only outstanding transfer orders + with self.export_data(url, {'outstanding': True}, export_format='tsv') as file: + self.process_csv( + file, + required_cols=required_cols, + excluded_cols=excluded_cols, + required_rows=models.TransferOrder.objects.filter( + status__in=TransferOrderStatusGroups.OPEN + ).count(), + delimiter='\t', + ) + + +class TransferOrderAllocateTest(OrderTest): + """Unit tests for allocating stock items against a TransferOrder.""" + + @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('transfer_order.add') + + self.url = reverse('api-transfer-order-allocate', kwargs={'pk': 1}) + self.url_serialized = reverse( + 'api-transfer-order-allocate-serials', kwargs={'pk': 1} + ) + + self.order = models.TransferOrder.objects.get(pk=1) + + # Create some line items for this transfer order + parts = Part.objects.exclude(virtual=True) + + for part in parts: + # Create a new line item + models.TransferOrderLineItem.objects.create( + order=self.order, part=part, quantity=5 + ) + + # Ensure we have stock! + StockItem.objects.create(part=part, quantity=100) + + # Create a new shipment against this TransferOrder + # self.shipment = models.TransferOrderShipment.objects.create(order=self.order) + + def test_invalid(self): + """Test POST with invalid data.""" + # No data + response = self.post(self.url, {}, expected_code=400) + + self.assertIn('This field is required', str(response.data['items'])) + + # Test with a single line items + line = self.order.lines.first() + part = line.part + + # Valid stock_item, but quantity is invalid + data = { + 'items': [ + { + 'line_item': line.pk, + 'stock_item': part.stock_items.last().pk, + 'quantity': 0, + } + ] + } + + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Quantity must be positive', str(response.data['items'])) + + # Valid stock item, too much quantity + data['items'][0]['quantity'] = 250 + + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Available quantity (100) exceeded', str(response.data['items'])) + + def test_allocate(self): + """Test that the allocation endpoint acts as expected, when provided with valid data!""" + # First, check that there are no line items allocated against this TransferOrder + self.assertEqual(self.order.stock_allocations.count(), 0) + + data = {'items': []} + + for line in self.order.lines.all(): + for stock_item in line.part.stock_items.filter(quantity__gt=5): + # Find a non-serialized stock item to allocate + if not stock_item.serialized: + break + + # Fully-allocate each line + data['items'].append({ + 'line_item': line.pk, + 'stock_item': stock_item.pk, + 'quantity': 5, + }) + + self.post(self.url, data, expected_code=201) + + # There should have been 1 stock item allocated against each line item + n_lines = self.order.lines.count() + + self.assertEqual(self.order.stock_allocations.count(), n_lines) + + for line in self.order.lines.all(): + self.assertEqual(line.allocations.count(), 1) + + def test_allocate_serials(self): + """Test that the allocation endpoint acts as expected, when provided with serials.""" + self.assertEqual(self.order.stock_allocations.count(), 0) + + trackable_lines = self.order.lines.filter(part__trackable=True) + for line in trackable_lines: + stock_item = ( + line.part.stock_items + .exclude(serial=None) + .filter(StockItem.IN_STOCK_FILTER) + .first() + ) + + # Allocate this serialized item to the transfer order + data = { + 'line_item': line.pk, + 'quantity': 1, + 'serial_numbers': stock_item.serial, + } + + self.post(self.url_serialized, data, expected_code=201) + + # There should have been 1 stock item allocated against each line item + n_lines = trackable_lines.count() + self.assertEqual(self.order.stock_allocations.count(), n_lines) + + for line in trackable_lines.all(): + self.assertEqual(line.allocations.count(), 1) + + def test_allocate_variant(self): + """Test that the allocation endpoint acts as expected, when provided with variant.""" + # First, check that there are no line items allocated against this TransferOrder + self.assertEqual(self.order.stock_allocations.count(), 0) + + data = {'items': []} + + def check_template(line_item): + return line_item.part.is_template + + for line in filter(check_template, self.order.lines.all()): + stock_item: Optional[StockItem] = None + + stock_item = None + + # Allocate a matching variant + parts: list[Part] = ( + Part.objects + .exclude(virtual=True) + .exclude(is_template=True) + .filter(variant_of=line.part.pk) + ) + # if we don't have a matching variant, continue + if not parts.exists(): + continue + for part in parts: + # ensure we have the quantity necessary to allocate + if not part.stock_items.filter(quantity__gt=5).exists(): + continue + + stock_item = part.stock_items.last() + + for item in part.stock_items.filter(quantity__gt=5): + if item.serialized: + continue + + stock_item = item + break + + if stock_item is not None: + break + + if stock_item is None: + raise self.fail('No stock item found for part') # pragma: no cover + + # Fully-allocate each line + data['items'].append({ + 'line_item': line.pk, + 'stock_item': stock_item.pk, + 'quantity': 5, + }) + + self.post(self.url, data, expected_code=201) + + # At least one item should be allocated, and all should be variants + self.assertGreater(self.order.stock_allocations.count(), 0) + for allocation in self.order.stock_allocations.all(): + self.assertNotEqual(allocation.item.part.pk, allocation.line.part.pk) + + def test_output_options(self): + """Test the various output options for the SalesOrderAllocation detail endpoint.""" + self.run_output_test( + reverse('api-transfer-order-allocation-list'), + ['part_detail', 'item_detail', 'order_detail', 'location_detail'], + assert_subset=True, + ) diff --git a/src/backend/InvenTree/order/test_sales_order.py b/src/backend/InvenTree/order/test_sales_order.py index 1a42a7549a..0186cfd90c 100644 --- a/src/backend/InvenTree/order/test_sales_order.py +++ b/src/backend/InvenTree/order/test_sales_order.py @@ -287,8 +287,15 @@ class SalesOrderTest(InvenTreeTestCase): # Mark the shipments as complete self.shipment.complete_shipment(None) + self.shipment.refresh_from_db() self.assertTrue(self.shipment.is_complete()) + # Check that each of the items have now been allocated to the customer + for allocation in self.shipment.allocations.all(): + item = allocation.item + self.assertEqual(item.customer, self.order.customer) + self.assertEqual(item.sales_order, self.order) + # Now, should be OK to ship result = self.order.ship_order(None) @@ -329,6 +336,88 @@ class SalesOrderTest(InvenTreeTestCase): self.assertEqual(self.line.fulfilled_quantity(), 50) self.assertEqual(self.line.allocated_quantity(), 50) + def test_shipment_many_items(self): + """Test completion of a shipment with many items. + + Here, we create a shipment with a very large number of items assigned, + and check that the shipment can be completed without error. + + 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. + + Ref: https://github.com/inventree/InvenTree/pull/11500 + """ + customer = Company.objects.create(name='Customer 2', is_customer=True) + + # Create a new SalesOrder + so = SalesOrder.objects.create(customer=customer, reference='SO-5678') + + shipment = so.shipments.first() + + if not shipment: + shipment = SalesOrderShipment.objects.create( + reference='SHIP-MENT', order=so + ) + + # Create a part + part = Part.objects.create(name='Part 1', salable=True) + + N_ITEMS = 750 + + line = SalesOrderLineItem.objects.create(part=part, order=so, quantity=N_ITEMS) + + # Create stock items, and assign to shipment + 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, + ) + ) + + StockItem.objects.bulk_create(stock_items) + + # Check expected available quantity + self.assertEqual(part.total_stock, 2250) + + # Allocate a single quantity from each stock item to the shipment + for item in StockItem.objects.filter(part=part): + allocations.append( + SalesOrderAllocation( + line=line, shipment=shipment, item=item, quantity=1 + ) + ) + + SalesOrderAllocation.objects.bulk_create(allocations) + + # Validate initial conditions for the SalesOrderShipment + self.assertEqual(shipment.allocations.count(), N_ITEMS) + self.assertIsNone(shipment.shipment_date) + self.assertFalse(shipment.is_complete()) + self.assertTrue(shipment.check_can_complete(raise_error=False)) + + # Complete the shipment + shipment.complete_shipment(None) + + shipment.refresh_from_db() + self.assertIsNotNone(shipment.shipment_date) + self.assertTrue(shipment.is_complete()) + + # Part stock quantity should have reduced by 1 for each allocated item + part.refresh_from_db() + self.assertEqual(part.total_stock, 2250 - N_ITEMS) + def test_default_shipment(self): """Test sales order default shipment creation.""" # Default setting value should be False diff --git a/src/backend/InvenTree/order/tests.py b/src/backend/InvenTree/order/tests.py index 1712f68759..e4e04c82ee 100644 --- a/src/backend/InvenTree/order/tests.py +++ b/src/backend/InvenTree/order/tests.py @@ -25,7 +25,17 @@ from part.models import Part from stock.models import StockItem, StockLocation from users.models import Owner -from .models import PurchaseOrder, PurchaseOrderExtraLine, PurchaseOrderLineItem +from .models import ( + PurchaseOrder, + PurchaseOrderExtraLine, + PurchaseOrderLineItem, + ReturnOrder, + ReturnOrderExtraLine, + ReturnOrderLineItem, + SalesOrder, + SalesOrderExtraLine, + SalesOrderLineItem, +) class OrderTest(ExchangeRateMixin, PluginRegistryMixin, TestCase): @@ -369,7 +379,8 @@ class OrderTest(ExchangeRateMixin, PluginRegistryMixin, TestCase): order=po, part=sp_1, quantity=3, - purchase_price=Money(1000, 'USD'), # "Unit price" should be $100USD + # "Unit price" should be $100USD + purchase_price=Money(1000, 'USD'), ) # 13 x 0.1 = 1.3 @@ -569,3 +580,151 @@ class OrderTest(ExchangeRateMixin, PluginRegistryMixin, TestCase): p.set_metadata(k, k) self.assertEqual(len(p.metadata.keys()), 4) + + +class OrderUpdatedAtTest(TestCase): + """Tests to verify that the updated_at field is correctly maintained on all order types.""" + + def setUp(self): + """Set up objects for all three order types.""" + self.supplier = Company.objects.filter(is_supplier=True).first() + self.customer = Company.objects.filter(is_customer=True).first() + + self.po = PurchaseOrder.objects.create( + reference='PO-TEST-001', supplier=self.supplier + ) + self.so = SalesOrder.objects.create( + reference='SO-TEST-001', customer=self.customer + ) + self.ro = ReturnOrder.objects.create( + reference='RO-TEST-001', customer=self.customer + ) + + self.part = Part.objects.create(name='Test Part', description='Test Part') + self.stock_item = StockItem.objects.create(part=self.part, quantity=10) + + def _refresh(self, instance): + """Return a fresh copy of the instance from the database.""" + return instance.__class__.objects.get(pk=instance.pk) + + def test_updated_at_set_on_save(self): + """updated_at should be populated after the order is saved.""" + for instance in [self.po, self.so, self.ro]: + self.assertIsNotNone(self._refresh(instance).updated_at) + + def test_updated_at_changes_on_save(self): + """updated_at should advance when the order is saved again.""" + for instance in [self.po, self.so, self.ro]: + original = self._refresh(instance).updated_at + + instance.description = 'Updated description' + instance.save() + + refreshed = self._refresh(instance) + self.assertGreaterEqual(refreshed.updated_at, original) + + def test_updated_at_on_extra_line_add(self): + """updated_at should advance on the parent order when an extra line is added.""" + for instance, ExtraLine in [ + (self.po, PurchaseOrderExtraLine), + (self.so, SalesOrderExtraLine), + (self.ro, ReturnOrderExtraLine), + ]: + before = self._refresh(instance).updated_at + + ExtraLine.objects.create(order=instance, quantity=1) + + after = self._refresh(instance).updated_at + self.assertGreaterEqual(after, before) + + def test_updated_at_on_extra_line_update(self): + """updated_at should advance on the parent order when an extra line is updated.""" + for instance, ExtraLine in [ + (self.po, PurchaseOrderExtraLine), + (self.so, SalesOrderExtraLine), + (self.ro, ReturnOrderExtraLine), + ]: + line = ExtraLine.objects.create(order=instance, quantity=1) + + before = self._refresh(instance).updated_at + + line.quantity = 5 + line.save() + + after = self._refresh(instance).updated_at + self.assertGreaterEqual(after, before) + + def test_updated_at_on_extra_line_delete(self): + """updated_at should advance on the parent order when an extra line is deleted.""" + for instance, ExtraLine in [ + (self.po, PurchaseOrderExtraLine), + (self.so, SalesOrderExtraLine), + (self.ro, ReturnOrderExtraLine), + ]: + line = ExtraLine.objects.create(order=instance, quantity=1) + + before = self._refresh(instance).updated_at + + line.delete() + + after = self._refresh(instance).updated_at + self.assertGreaterEqual(after, before) + + def test_updated_at_on_line_item_add(self): + """updated_at should advance on the parent order when a regular line item is added.""" + before_po = self._refresh(self.po).updated_at + PurchaseOrderLineItem.objects.create(order=self.po, part=None, quantity=1) + self.assertGreaterEqual(self._refresh(self.po).updated_at, before_po) + + before_so = self._refresh(self.so).updated_at + SalesOrderLineItem.objects.create(order=self.so, part=None, quantity=1) + self.assertGreaterEqual(self._refresh(self.so).updated_at, before_so) + + before_ro = self._refresh(self.ro).updated_at + ReturnOrderLineItem.objects.create( + order=self.ro, item=self.stock_item, quantity=1 + ) + self.assertGreaterEqual(self._refresh(self.ro).updated_at, before_ro) + + def test_updated_at_on_line_item_update(self): + """updated_at should advance on the parent order when a regular line item is updated.""" + po_line = PurchaseOrderLineItem.objects.create( + order=self.po, part=None, quantity=1 + ) + so_line = SalesOrderLineItem.objects.create( + order=self.so, part=None, quantity=1 + ) + ro_line = ReturnOrderLineItem.objects.create( + order=self.ro, item=self.stock_item, quantity=1 + ) + + for instance, line in [ + (self.po, po_line), + (self.so, so_line), + (self.ro, ro_line), + ]: + before = self._refresh(instance).updated_at + line.quantity = 5 + line.save() + self.assertGreaterEqual(self._refresh(instance).updated_at, before) + + def test_updated_at_on_line_item_delete(self): + """updated_at should advance on the parent order when a regular line item is deleted.""" + po_line = PurchaseOrderLineItem.objects.create( + order=self.po, part=None, quantity=1 + ) + so_line = SalesOrderLineItem.objects.create( + order=self.so, part=None, quantity=1 + ) + ro_line = ReturnOrderLineItem.objects.create( + order=self.ro, item=self.stock_item, quantity=1 + ) + + for instance, line in [ + (self.po, po_line), + (self.so, so_line), + (self.ro, ro_line), + ]: + before = self._refresh(instance).updated_at + line.delete() + self.assertGreaterEqual(self._refresh(instance).updated_at, before) diff --git a/src/backend/InvenTree/order/validators.py b/src/backend/InvenTree/order/validators.py index a4873679bd..ce2004de76 100644 --- a/src/backend/InvenTree/order/validators.py +++ b/src/backend/InvenTree/order/validators.py @@ -22,6 +22,13 @@ def generate_next_return_order_reference(): return ReturnOrder.generate_reference() +def generate_next_transfer_order_reference(): + """Generate the next available TransferOrder reference.""" + from order.models import TransferOrder + + return TransferOrder.generate_reference() + + def validate_sales_order_reference_pattern(pattern): """Validate the SalesOrder reference 'pattern' setting.""" from order.models import SalesOrder @@ -62,3 +69,17 @@ def validate_return_order_reference(value): from order.models import ReturnOrder ReturnOrder.validate_reference_field(value) + + +def validate_transfer_order_reference_pattern(pattern): + """Validate the TransferOrder reference 'pattern' setting.""" + from order.models import TransferOrder + + TransferOrder.validate_reference_pattern(pattern) + + +def validate_transfer_order_reference(value): + """Validate that the ReturnOrder reference field matches the required pattern.""" + from order.models import TransferOrder + + TransferOrder.validate_reference_field(value) diff --git a/src/backend/InvenTree/part/api.py b/src/backend/InvenTree/part/api.py index 3d03cfa9a9..2b4e79421f 100644 --- a/src/backend/InvenTree/part/api.py +++ b/src/backend/InvenTree/part/api.py @@ -8,10 +8,11 @@ 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.types import OpenApiTypes -from drf_spectacular.utils import extend_schema_field +from drf_spectacular.utils import extend_schema, extend_schema_field from rest_framework import serializers from rest_framework.response import Response +import common.serializers import part.tasks as part_tasks from data_exporter.mixins import DataExportViewMixin from InvenTree.api import ( @@ -23,9 +24,7 @@ from InvenTree.api import ( from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( ORDER_FILTER, - ORDER_FILTER_ALIAS, SEARCH_ORDER_FILTER, - SEARCH_ORDER_FILTER_ALIAS, InvenTreeDateFilter, InvenTreeSearchFilter, NumberOrNullFilter, @@ -74,20 +73,6 @@ class CategoryMixin: queryset = part_serializers.CategorySerializer.annotate_queryset(queryset) return queryset - def get_serializer_context(self): - """Add extra context to the serializer for the CategoryDetail endpoint.""" - ctx = super().get_serializer_context() - - try: - ctx['starred_categories'] = [ - star.category for star in self.request.user.starred_categories.all() - ] - except AttributeError: - # Error is thrown if the view does not have an associated request - ctx['starred_categories'] = [] - - return ctx - class CategoryFilter(FilterSet): """Custom filterset class for the PartCategoryList endpoint.""" @@ -161,7 +146,7 @@ class CategoryFilter(FilterSet): Note: If the "parent" filter is provided, we offload the logic to that method. """ - parent = str2bool(self.data.get('parent', None)) + parent = self.data.get('parent', None) top_level = str2bool(self.data.get('top_level', None)) # If the parent is *not* provided, update the results based on the "cascade" value @@ -267,21 +252,23 @@ class CategoryDetail(CategoryMixin, OutputOptionsMixin, CustomRetrieveUpdateDest """Perform 'update' function and mark this part as 'starred' (or not).""" # Clean up input data data = self.clean_data(request.data) + response = super().update(request, *args, **kwargs) if 'starred' in data: starred = str2bool(data.get('starred', False)) self.get_object().set_starred(request.user, starred, include_parents=False) - response = super().update(request, *args, **kwargs) - return response def destroy(self, request, *args, **kwargs): """Delete a Part category instance via the API.""" - delete_parts = str2bool(request.data.get('delete_parts', False)) + serializer = part_serializers.CategoryDeleteSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + + delete_parts = str2bool(serializer.validated_data.get('delete_parts', False)) delete_child_categories = str2bool( - request.data.get('delete_child_categories', False) + serializer.validated_data.get('delete_child_categories', False) ) return super().destroy( @@ -301,7 +288,7 @@ class CategoryTree(ListAPI): queryset = PartCategory.objects.all() serializer_class = part_serializers.CategoryTree - filter_backends = ORDER_FILTER_ALIAS + filter_backends = ORDER_FILTER ordering_fields = ['level', 'name', 'subcategories'] @@ -614,9 +601,20 @@ class PartValidateBOM(RetrieveUpdateAPI): queryset = Part.objects.all() serializer_class = part_serializers.PartBomValidateSerializer + role_required = 'bom' + @extend_schema( + responses={ + 200: common.serializers.TaskDetailSerializer, + 404: common.serializers.TaskDetailSerializer, + } + ) def update(self, request, *args, **kwargs): - """Validate the referenced BomItem instance.""" + """Validate the referenced BomItem instance. + + As this task is offloaded to the background worker, + we return information about the background task which is performing the validation. + """ part = self.get_object() partial = kwargs.pop('partial', False) @@ -630,7 +628,7 @@ class PartValidateBOM(RetrieveUpdateAPI): valid = str2bool(serializer.validated_data.get('valid', False)) # BOM validation may take some time, so we offload it to a background task - offload_task( + task_id = offload_task( part_tasks.validate_bom, part.pk, valid, @@ -638,10 +636,8 @@ class PartValidateBOM(RetrieveUpdateAPI): group='part', ) - # Re-serialize the response - serializer = self.get_serializer(part, many=False) - - return Response(serializer.data) + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) class PartFilter(FilterSet): @@ -735,6 +731,23 @@ class PartFilter(FilterSet): # Filter items which have an 'in_stock' level higher than 'minimum_stock' return queryset.filter(Q(total_in_stock__gte=F('minimum_stock'))) + high_stock = rest_filters.BooleanFilter( + label='High stock', method='filter_high_stock' + ) + + def filter_high_stock(self, queryset, name, value): + """Filter by "high stock" status.""" + if str2bool(value): + # Ignore any parts which do not have a specified 'maximum_stock' level + # Filter items which have an 'in_stock' level higher than 'maximum_stock' + return queryset.exclude(maximum_stock=0).filter( + Q(total_in_stock__gt=F('maximum_stock')) + ) + # Filter items which have an 'in_stock' level lower than 'maximum_stock' + return queryset.filter( + Q(total_in_stock__lte=F('maximum_stock')) | Q(maximum_stock=0) + ).distinct() + # has_stock filter has_stock = rest_filters.BooleanFilter(label='Has stock', method='filter_has_stock') @@ -1028,27 +1041,8 @@ class PartMixin(SerializerContextMixin): # Indicate that we can create a new Part via this endpoint kwargs['create'] = self.is_create - # Pass a list of "starred" parts to the current user to the serializer - # We do this to reduce the number of database queries required! - if ( - self.starred_parts is None - and self.request is not None - and hasattr(self.request.user, 'starred_parts') - ): - self.starred_parts = [ - star.part for star in self.request.user.starred_parts.all() - ] - kwargs['starred_parts'] = self.starred_parts - return super().get_serializer(*args, **kwargs) - def get_serializer_context(self): - """Extend serializer context data.""" - context = super().get_serializer_context() - context['request'] = self.request - - return context - class PartOutputOptions(OutputConfiguration): """Output options for Part endpoints.""" @@ -1079,9 +1073,10 @@ class PartList( filterset_class = PartFilter is_create = True - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER ordering_fields = [ + 'id', 'name', 'creation_date', 'IPN', @@ -1133,6 +1128,7 @@ class PartDetail(PartMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI): """ # Clean input data data = self.clean_data(request.data) + response = super().update(request, *args, **kwargs) if 'starred' in data: starred = str2bool(data.get('starred', False)) @@ -1141,8 +1137,6 @@ class PartDetail(PartMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI): request.user, starred, include_variants=False, include_categories=False ) - response = super().update(request, *args, **kwargs) - return response @@ -1315,6 +1309,10 @@ class BomFilter(FilterSet): label=_('Assembly part is testable'), field_name='part__testable' ) + part_locked = rest_filters.BooleanFilter( + label=_('Assembly part is locked'), field_name='part__locked' + ) + # Filters for linked 'sub_part' sub_part_active = rest_filters.BooleanFilter( label=_('Component part is active'), field_name='sub_part__active' @@ -1431,7 +1429,11 @@ class BomOutputOptions(OutputConfiguration): class BomList( - BomMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateDestroyAPIView + BomMixin, + BulkUpdateMixin, + DataExportViewMixin, + OutputOptionsMixin, + ListCreateDestroyAPIView, ): """API endpoint for accessing a list of BomItem objects. @@ -1441,7 +1443,7 @@ class BomList( output_options = BomOutputOptions filterset_class = BomFilter - filter_backends = SEARCH_ORDER_FILTER_ALIAS + filter_backends = SEARCH_ORDER_FILTER search_fields = [ 'reference', diff --git a/src/backend/InvenTree/part/filters.py b/src/backend/InvenTree/part/filters.py index 92887e57c8..2c832c2e9e 100644 --- a/src/backend/InvenTree/part/filters.py +++ b/src/backend/InvenTree/part/filters.py @@ -37,7 +37,11 @@ from sql_util.utils import SubquerySum import part.models import stock.models from build.status_codes import BuildStatusGroups -from order.status_codes import PurchaseOrderStatusGroups, SalesOrderStatusGroups +from order.status_codes import ( + PurchaseOrderStatusGroups, + SalesOrderStatusGroups, + TransferOrderStatusGroups, +) def annotate_in_production_quantity(reference: str = '') -> QuerySet: @@ -171,7 +175,14 @@ def annotate_build_order_requirements(reference: str = '') -> QuerySet: build_filter = Q(build__status__in=BuildStatusGroups.ACTIVE_CODES) return Coalesce( - SubquerySum(f'{reference}used_in__build_lines__quantity', filter=build_filter), + SubquerySum( + ExpressionWrapper( + F(f'{reference}used_in__build_lines__quantity') + - F(f'{reference}used_in__build_lines__consumed'), + output_field=DecimalField(), + ), + filter=build_filter, + ), Decimal(0), output_field=models.DecimalField(), ) @@ -267,6 +278,40 @@ def annotate_sales_order_allocations(reference: str = '', location=None) -> Quer ) +def annotate_transfer_order_allocations(reference: str = '', location=None) -> QuerySet: + """Annotate the total quantity of each part allocated to transfer orders. + + - This function calculates the total part quantity allocated to open transfer orders" + - Finds all transfer order allocations for each part (using the provided filter) + - Aggregates the 'allocated quantity' for each relevant transfer order allocation item + + Arguments: + reference: The relationship reference of the part from the current model + location: If provided, only allocated stock items from this location are considered + """ + # Order filter only returns open orders + order_filter = Q(line__order__status__in=TransferOrderStatusGroups.OPEN) + + if location is not None: + # Filter by location (including any child locations) + + order_filter &= Q( + item__location__tree_id=location.tree_id, + item__location__lft__gte=location.lft, + item__location__rght__lte=location.rght, + item__location__level__gte=location.level, + ) + + return Coalesce( + SubquerySum( + f'{reference}stock_items__transfer_order_allocations__quantity', + filter=order_filter, + ), + Decimal(0), + output_field=models.DecimalField(), + ) + + def variant_stock_query(reference: str = '', filter: Optional[Q] = None) -> QuerySet: """Create a queryset to retrieve all stock items for variant parts under the specified part. diff --git a/src/backend/InvenTree/part/fixtures/bom.yaml b/src/backend/InvenTree/part/fixtures/bom.yaml index e3763eb41f..0907593477 100644 --- a/src/backend/InvenTree/part/fixtures/bom.yaml +++ b/src/backend/InvenTree/part/fixtures/bom.yaml @@ -7,6 +7,7 @@ part: 100 sub_part: 1 quantity: 10 + raw_amount: '10' allow_variants: True # 40 x R_2K2_0805 @@ -16,6 +17,7 @@ part: 100 sub_part: 3 quantity: 40 + raw_amount: '40' # 25 x C_22N_0805 - model: part.bomitem @@ -24,6 +26,7 @@ part: 100 sub_part: 5 quantity: 25 + raw_amount: '25' reference: ABCDE # 3 x Orphan @@ -33,6 +36,7 @@ part: 100 sub_part: 50 quantity: 3 + raw_amount: '3' reference: VWXYZ - model: part.bomitem @@ -41,6 +45,7 @@ part: 1 sub_part: 5 quantity: 3 + raw_amount: '3' reference: LMNOP # Make "Assembly" from "Bob" @@ -50,6 +55,7 @@ part: 101 sub_part: 100 quantity: 10 + raw_amount: '10' - model: part.bomitemsubstitute pk: 1 diff --git a/src/backend/InvenTree/part/helpers.py b/src/backend/InvenTree/part/helpers.py index d07e3cfc13..7c55c9810e 100644 --- a/src/backend/InvenTree/part/helpers.py +++ b/src/backend/InvenTree/part/helpers.py @@ -5,7 +5,7 @@ import os from django.conf import settings import structlog -from jinja2 import Environment, select_autoescape +from jinja2.sandbox import SandboxedEnvironment from common.settings import get_global_setting @@ -37,11 +37,7 @@ def compile_full_name_template(*args, **kwargs): # Cache the template string _part_full_name_template_string = template_string - env = Environment( - autoescape=select_autoescape(default_for_string=False, default=False), - variable_start_string='{{', - variable_end_string='}}', - ) + env = SandboxedEnvironment(variable_start_string='{{', variable_end_string='}}') # Compile the template try: diff --git a/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py b/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py index 0924f9065e..1a8ddea9a8 100644 --- a/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py +++ b/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py @@ -24,6 +24,7 @@ def update_category_parameters(apps, schema_editor): PartCategoryParameterTemplate.objects.bulk_update( category_parameters_to_update, fields=["template"], + batch_size=250, ) @@ -47,6 +48,7 @@ def reverse_update_category_parameters(apps, schema_editor): PartCategoryParameterTemplate.objects.bulk_update( category_parameters_to_update, fields=["parameter_template"], + batch_size=250, ) diff --git a/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py b/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py new file mode 100644 index 0000000000..995e064556 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py @@ -0,0 +1,44 @@ +# Generated by Django 5.2.13 on 2026-04-27 22:33 + +from django.db import migrations + + +def update_bom_role(apps, schema_editor): + """Update the ruleset for the BOM role. + + As the 'bom' role was previously covered by the 'part' role, + we need to update the ruleset to include the correct models. + + """ + from users.ruleset import RuleSetEnum + + Group = apps.get_model("auth", "Group") + RuleSet = apps.get_model("users", "RuleSet") + + # For each existing group, create a new 'bom' ruleset + for group in Group.objects.all(): + # Find a matching 'part' ruleset for this group + if ruleset := RuleSet.objects.filter(name=RuleSetEnum.PART, group=group).first(): + # A 'part' ruleset exists for this group - create a new 'bom' ruleset based on this + ruleset.pk = None # Create a new instance + ruleset.name = RuleSetEnum.BOM + ruleset.save() + + else: + # No 'part' ruleset exists for this group - create a default 'bom' ruleset + RuleSet.objects.create( + name=RuleSetEnum.BOM, + group=group + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0147_remove_part_default_supplier"), + ("users", "0014_userprofile") + ] + + operations = [ + migrations.RunPython(update_bom_role, reverse_code=migrations.RunPython.noop), + ] diff --git a/src/backend/InvenTree/part/migrations/0149_bomitem_raw_amount.py b/src/backend/InvenTree/part/migrations/0149_bomitem_raw_amount.py new file mode 100644 index 0000000000..0f61638ae5 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0149_bomitem_raw_amount.py @@ -0,0 +1,86 @@ +# Generated by Django 5.2.12 on 2026-03-30 10:01 + +from decimal import Decimal + +from django.db import migrations, models + +from InvenTree.helpers import normalize + + +def set_default_raw_amount(apps, schema_editor): + """Initialize the 'raw_amount' field for existing BomItem records.""" + BomItem = apps.get_model("part", "BomItem") + + to_update = [] + updated_count = 0 + + # Run BulkUpdate in batches to avoid memory issues with large datasets + BATCH_SIZE = 100 + + N_BOM_ITEMS = BomItem.objects.count() + + def add_bom_item(item): + nonlocal to_update + nonlocal updated_count + + to_update.append(item) + + if len(to_update) >= BATCH_SIZE: + BomItem.objects.bulk_update(to_update, ["raw_amount"]) + updated_count += len(to_update) + to_update = [] + + for item in BomItem.objects.all(): + item.raw_amount = str(normalize(Decimal(item.quantity))) + add_bom_item(item) + + # Handle any remaining items that were not updated in the loop + if len(to_update) > 0: + BomItem.objects.bulk_update(to_update, ["raw_amount"]) + updated_count += len(to_update) + + assert updated_count == N_BOM_ITEMS, f"Expected to update {N_BOM_ITEMS} BomItem records, but updated {updated_count} records instead." + + assert BomItem.objects.filter(raw_amount="").count() == 0, "There are BomItem records with an empty 'raw_amount' field after migration." + + if updated_count > 0: + print(f"Initialized 'raw_amount' field for {updated_count} BomItem records.") + + +class Migration(migrations.Migration): + """Run a set of data and schema migrations to add a new 'raw_amount' field to the BomItem model. + + 1. Add a new 'raw_amount' field to the BomItem model, which is a CharField that can store a raw amount of sub-part consumed to produce one part. This field can be used to store fractional amounts or amounts with associated units (e.g. '10 hours', '5 kg', etc.). + 2. Run a data migration to initialize the 'raw_amount' field for existing BomItem records, by copying the value from the existing 'quantity' field and converting it to a string. + 3. Mark the 'raw_amount' field as blank=False, now that the quantity values have been copied across + """ + + dependencies = [ + ("part", "0148_auto_20260427_2233"), + ] + + operations = [ + migrations.AddField( + model_name="bomitem", + name="raw_amount", + field=models.CharField( + blank=True, + null=False, + help_text="Amount of sub-part consumed to produce one part", + max_length=25, + verbose_name="Amount", + ), + ), + migrations.RunPython(set_default_raw_amount, reverse_code=migrations.RunPython.noop), + migrations.AlterField( + model_name="bomitem", + name="raw_amount", + field=models.CharField( + blank=False, + null=False, + help_text="Amount of sub-part consumed to produce one part", + max_length=25, + verbose_name="Amount", + ), + ), + ] diff --git a/src/backend/InvenTree/part/migrations/0150_part_maximum_stock.py b/src/backend/InvenTree/part/migrations/0150_part_maximum_stock.py new file mode 100644 index 0000000000..439dc57b69 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0150_part_maximum_stock.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.13 on 2026-05-10 06:02 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0149_bomitem_raw_amount"), + ] + + operations = [ + migrations.AddField( + model_name="part", + name="maximum_stock", + field=models.DecimalField( + decimal_places=6, + default=0, + help_text="Maximum allowed stock level", + max_digits=19, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Maximum Stock", + ), + ), + ] diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index a5fb4c4e22..48b0bb0399 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -2,15 +2,14 @@ from __future__ import annotations -import decimal import hashlib import inspect import math import os import re from datetime import timedelta -from decimal import Decimal, InvalidOperation -from typing import cast +from decimal import ROUND_HALF_UP, Decimal, InvalidOperation +from typing import TypedDict, cast from django.conf import settings from django.contrib.auth.models import User @@ -61,6 +60,7 @@ from order.status_codes import ( PurchaseOrderStatus, PurchaseOrderStatusGroups, SalesOrderStatusGroups, + TransferOrderStatusGroups, ) from stock import models as StockModels @@ -427,7 +427,7 @@ class PartCategoryParameterTemplate(InvenTree.models.InvenTreeMetadataModel): ) -class PartReportContext(report.mixins.BaseReportContext): +class PartReportContext(report.mixins.BaseReportContext, TypedDict): """Report context for the Part model. Attributes: @@ -491,6 +491,7 @@ class Part( default_location: Where the item is normally stored (may be null) default_expiry: The default expiry duration for any StockItem instances of this part minimum_stock: Minimum preferred quantity to keep in stock + maximum_stock: Maximum 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? @@ -569,13 +570,13 @@ class Part( } def check_parameter_delete(self, parameter): - """Custom delete check for Paramteter instances associated with this Part.""" - if self.locked: + """Custom delete check for Parameter instances associated with this Part.""" + if self.locked and get_global_setting('PART_ENABLE_LOCKING'): raise ValidationError(_('Cannot delete parameters of a locked part')) def check_parameter_save(self, parameter): """Custom save check for Parameter instances associated with this Part.""" - if self.locked: + if self.locked and get_global_setting('PART_ENABLE_LOCKING'): raise ValidationError(_('Cannot modify parameters of a locked part')) def delete(self, **kwargs): @@ -586,7 +587,7 @@ class Part( - The part is still active - The part is used in a BOM for a different part. """ - if self.locked: + if self.locked and get_global_setting('PART_ENABLE_LOCKING'): raise ValidationError(_('Cannot delete this part as it is locked')) if self.active: @@ -776,18 +777,12 @@ class Part( 'revision_of': _('Part cannot be a revision of itself') }) - # Part cannot be a revision of a part which is itself a revision - if self.revision_of.revision_of: - raise ValidationError({ - 'revision_of': _( - 'Cannot make a revision of a part which is already a revision' - ) - }) - # If this part is a revision, it must have a revision code if not self.revision: raise ValidationError({ - 'revision': _('Revision code must be specified') + 'revision': _( + 'Revision code must be specified for a part marked as a revision' + ) }) if get_global_setting('PART_REVISION_ASSEMBLY_ONLY'): @@ -1238,6 +1233,15 @@ class Part( help_text=_('Minimum allowed stock level'), ) + maximum_stock = models.DecimalField( + max_digits=19, + decimal_places=6, + default=0, + validators=[MinValueValidator(0)], + verbose_name=_('Maximum Stock'), + help_text=_('Maximum allowed stock level'), + ) + units = models.CharField( max_length=20, default='', @@ -1765,8 +1769,50 @@ class Part( return query['total'] + def transfer_order_allocations(self, **kwargs): + """Return all transfer-order-allocation objects which allocate this part to a TransferOrder.""" + include_variants = kwargs.get('include_variants', True) + + queryset = OrderModels.TransferOrderAllocation.objects.all() + + if include_variants: + # Include allocations for all variants + variants = self.get_descendants(include_self=True) + queryset = queryset.filter(item__part__in=variants) + else: + # Only look at this part + queryset = queryset.filter(item__part=self) + + # Default behaviour is to only return *pending* allocations + pending = kwargs.get('pending', True) + + if pending is True: + # Look only for 'open' orders + queryset = queryset.filter( + line__order__status__in=TransferOrderStatusGroups.OPEN + ) + elif pending is False: + # Look only for 'closed' orders + queryset = queryset.exclude( + line__order__status__in=TransferOrderStatusGroups.OPEN + ) + + return queryset + + def transfer_order_allocation_count(self, **kwargs): + """Return the total quantity of this part allocated to transfer orders.""" + query = self.transfer_order_allocations(**kwargs).aggregate( + total=Coalesce( + Sum('quantity', output_field=models.DecimalField()), + 0, + output_field=models.DecimalField(), + ) + ) + + return query['total'] + def allocation_count(self, **kwargs): - """Return the total quantity of stock allocated for this part, against both build orders and sales orders.""" + """Return the total quantity of stock allocated for this part, against build orders, sales orders, and transfer orders.""" if self.id is None: # If this instance has not been saved, foreign-key lookups will fail return 0 @@ -1774,6 +1820,8 @@ class Part( return sum([ self.build_order_allocation_count(**kwargs), self.sales_order_allocation_count(**kwargs), + # For now, stock allocated to a transfer order will not impact its availability + # self.transfer_order_allocation_count(**kwargs), ]) def stock_entries( @@ -2048,8 +2096,9 @@ class Part( 'part', 'sub_part' ) - for item in bom_items: - item.validate_hash(valid=valid) + if valid: + for item in bom_items: + item.validate_hash(valid=True) self.bom_validated = valid self.bom_checksum = self.get_bom_hash() if valid else '' @@ -2064,8 +2113,13 @@ class Part( Note: Does *NOT* delete inherited BOM items! """ + import part.tasks as part_tasks + self.bom_items.all().delete() + # Offload task to re-validate the BOM for this assembly + InvenTree.tasks.offload_task(part_tasks.check_bom_valid, self.pk, group='part') + def getRequiredParts(self, recursive=False, parts=None): """Return a list of parts required to make this part (i.e. BOM items). @@ -2224,8 +2278,8 @@ class Part( logger.warning('WARNING: BomItem ID %s contains itself in BOM', item.pk) continue - q = decimal.Decimal(quantity) - i = decimal.Decimal(item.quantity) + q = Decimal(quantity) + i = Decimal(item.quantity) prices = item.sub_part.get_price_range( q * i, internal=internal, purchase=purchase @@ -2463,7 +2517,7 @@ class Part( templates.append(template) if len(templates) > 0: - PartTestTemplate.objects.bulk_create(templates) + PartTestTemplate.objects.bulk_create(templates, batch_size=250) @transaction.atomic def copy_category_parameters(self, category: PartCategory): @@ -2479,6 +2533,7 @@ class Part( category__in=categories ).order_by('-category__level') + template_ids = set() parameters = [] content_type = ContentType.objects.get_for_model(Part) @@ -2489,6 +2544,12 @@ class Part( ).exists(): continue + # Ensure we do not create duplicate parameters if multiple categories have the same template + if category_template.template.pk in template_ids: + continue + + template_ids.add(category_template.template.pk) + parameters.append( Parameter( template=category_template.template, @@ -2498,8 +2559,7 @@ class Part( ) ) - if len(parameters) > 0: - Parameter.objects.bulk_create(parameters) + Parameter.objects.bulk_create(parameters, batch_size=250) def getTestTemplates( self, required=None, include_parent: bool = True, enabled=None @@ -2582,21 +2642,22 @@ class Part( Note that some supplier parts may have a different pack_quantity attribute, and this needs to be taken into account! """ + from order.models import PurchaseOrderLineItem + quantity = 0 - # Iterate through all supplier parts - for sp in self.supplier_parts.all(): - # Look at any incomplete line item for open orders - lines = sp.purchase_order_line_items.filter( - order__status__in=PurchaseOrderStatusGroups.OPEN, - quantity__gt=F('received'), - ) + # Find all outstanding PurchaseOrderLineItem objects which reference this part + lines = PurchaseOrderLineItem.objects.filter( + order__status__in=PurchaseOrderStatusGroups.OPEN, + part__part_id=self.pk, + quantity__gt=F('received'), + ).prefetch_related('part') - for line in lines: - remaining = line.quantity - line.received + for line in lines: + remaining = line.quantity - line.received - if remaining > 0: - quantity += sp.base_quantity(remaining) + if remaining > 0: + quantity += line.part.base_quantity(remaining) return quantity @@ -2630,9 +2691,7 @@ class Part( parts = [] # Child parts - children = self.get_descendants(include_self=False) - - for child in children: + for child in self.get_descendants(include_self=False): parts.append(child) # Immediate parent, and siblings @@ -3778,7 +3837,8 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): Attributes: part: Link to the parent part (the part that will be produced) sub_part: Link to the child part (the part that will be consumed) - quantity: Number of 'sub_parts' consumed to produce one 'part' + raw_amount: Raw amount of 'sub_part' consumed to produce one 'part' (can be fractional, or use an associated unit) + quantity: Numerical quantity of 'sub_parts' consumed to produce one 'part' optional: Boolean field describing if this BomItem is optional consumable: Boolean field describing if this BomItem is considered a 'consumable' reference: BOM reference field (e.g. part designators) @@ -3880,6 +3940,61 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): """ return Q(part__in=self.get_valid_parts_for_allocation()) + def set_quantity(self, quantity: Decimal | str | float): + """Update the 'quantity' for this BomItem.""" + self.raw_amount = quantity + self.recalculate_quantity() + + def recalculate_quantity(self): + """Recalculate the 'quantity' field based on the 'raw_amount' field.""" + if self.raw_amount is None or self.raw_amount == '': + self.raw_amount = self.quantity + + # Convert from the "raw amount" to a numerical quantity, using the associated unit (if specified) + try: + quantity = InvenTree.conversion.convert_physical_value( + self.raw_amount, self.sub_part.units, strip_units=False + ) + + if not self.sub_part.units and not InvenTree.conversion.is_dimensionless( + quantity + ): + raise ValidationError({ + 'raw_amount': _('Invalid quantity - no units specified for part') + }) + + allow_zero_qty = get_global_setting('PART_BOM_ALLOW_ZERO_QUANTITY', False) + + if allow_zero_qty: + if float(quantity.magnitude) < 0: + raise ValidationError({ + 'raw_amount': _( + 'Quantity must be greater than or equal to zero' + ) + }) + + else: + if float(quantity.magnitude) <= 0: + raise ValidationError({ + 'raw_amount': _('Quantity must be greater than zero') + }) + + # Normalize the quantity, to maximum 5 decimal places + quantity = Decimal(quantity.magnitude) + + except ValidationError as e: + raise ValidationError({'raw_amount': e.messages}) + + # Ensure that the raw_amount is converted to a Decimal value + # and quantized to a maximum of 5 decimal places (to avoid floating point issues) + try: + self.quantity = Decimal(quantity).quantize( + Decimal('0.00001'), rounding=ROUND_HALF_UP + ) + except InvalidOperation: + msg = _('Invalid quantity provided') + raise ValidationError({'quantity': msg, 'raw_amount': msg}) + def delete(self): """Check if this item can be deleted.""" import part.tasks as part_tasks @@ -3928,9 +4043,12 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): assemblies = set() if db_instance: - # Find all assemblies which use this BomItem *after* we save + # Find all assemblies which use this BomItem *before* we save assemblies.update(db_instance.get_assemblies()) + # Update the set of assemblies to include those which use this BomItem *after* we save + assemblies.update(self.get_assemblies()) + for assembly in assemblies: # Offload task to update the checksum for this assembly InvenTree.tasks.offload_task( @@ -3948,7 +4066,8 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): Raises: ValidationError: If the assembly is locked """ - # TODO: Perhaps control this with a global setting? + if not get_global_setting('PART_ENABLE_LOCKING'): + return if assembly.locked: raise ValidationError(_('BOM item cannot be modified - assembly is locked')) @@ -3983,7 +4102,15 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): limit_choices_to={'component': True}, ) - # Quantity required + raw_amount = models.CharField( + max_length=25, + verbose_name=_('Amount'), + help_text=_('Amount of sub-part consumed to produce one part'), + blank=False, + null=False, + ) + + # Native quantity required quantity = models.DecimalField( default=1.0, max_digits=15, @@ -4084,7 +4211,9 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): These fields are used to calculate the checksum hash of this BOM item. """ return [ + 'part', 'part_id', + 'sub_part', 'sub_part_id', 'quantity', 'setup_quantity', @@ -4167,10 +4296,8 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): """ super().clean() - try: - self.quantity = Decimal(self.quantity) - except InvalidOperation: - raise ValidationError({'quantity': _('Must be a valid number')}) + # Recalculate the 'quantity' field based on the 'raw_amount' field + self.recalculate_quantity() try: # Check for circular BOM references @@ -4215,7 +4342,7 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): if n <= 0: return 0.0 - return int(available_stock / n) + return int(Decimal(available_stock) / n) def get_required_quantity(self, build_quantity: float) -> float: """Calculate the required part quantity, based on the supplied build_quantity. diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index bb27afe074..ccbce76492 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -1,11 +1,9 @@ """DRF data serializers for Part app.""" -import io import os from decimal import Decimal from django.core.exceptions import ValidationError -from django.core.files.base import ContentFile from django.core.validators import MinValueValidator from django.db import models, transaction from django.db.models import ExpressionWrapper, F, Q @@ -24,6 +22,7 @@ import common.currency import common.filters import common.serializers import company.models +import InvenTree.conversion import InvenTree.helpers import InvenTree.serializers import part.filters as part_filters @@ -34,13 +33,7 @@ from data_exporter.mixins import DataExportSerializerMixin from importer.registry import register_importer from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.ready import isGeneratingSchema -from InvenTree.serializers import ( - FilterableDateTimeField, - FilterableFloatField, - FilterableListField, - FilterableListSerializer, - enable_filter, -) +from InvenTree.serializers import OptionalField, TreePathSerializer from users.serializers import UserSerializer from .models import ( @@ -61,6 +54,27 @@ from .models import ( logger = structlog.get_logger('inventree') +class CategoryDeleteSerializer(serializers.Serializer): + """Serializer for deleting a PartCategory instance.""" + + class Meta: + """Metaclass options.""" + + fields = ['delete_child_categories', 'delete_parts'] + + delete_child_categories = serializers.BooleanField( + label=_('Delete Subcategories'), + help_text=_('Delete all sub-categories contained within this category'), + required=True, + ) + + delete_parts = serializers.BooleanField( + label=_('Delete Parts'), + help_text=_('Delete all parts contained within this category'), + required=True, + ) + + @register_importer() class CategorySerializer( InvenTree.serializers.FilterableSerializerMixin, @@ -129,15 +143,26 @@ class CategorySerializer( def get_starred(self, category) -> bool: """Return True if the category is directly "starred" by the current user.""" - return category in self.context.get('starred_categories', []) + if not self.request or not self.request.user: + return False - path = enable_filter( - FilterableListField( - child=serializers.DictField(), - source='get_path', - read_only=True, - allow_null=True, - ), + # Cache the "starred_categories" list for the current user + if not hasattr(self, 'starred_categories'): + self.starred_categories = [ + star.category.pk for star in self.request.user.starred_categories.all() + ] + + return category.pk in self.starred_categories + + path = OptionalField( + serializer_class=TreePathSerializer, + serializer_kwargs={ + 'source': 'get_path', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='path_detail', ) @@ -344,18 +369,25 @@ class PartBriefSerializer( ) # Pricing fields - pricing_min = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='pricing_data.overall_min', allow_null=True, read_only=True - ), - True, + pricing_min = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'pricing_data.overall_min', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) - pricing_max = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='pricing_data.overall_max', allow_null=True, read_only=True - ), - True, + + pricing_max = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'pricing_data.overall_max', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) @@ -546,7 +578,6 @@ class PartSerializer( InvenTree.serializers.FilterableSerializerMixin, DataImportExportSerializerMixin, InvenTree.serializers.NotesFieldMixin, - InvenTree.serializers.RemoteImageMixin, InvenTree.serializers.InvenTreeTaggitSerializer, InvenTree.serializers.InvenTreeModelSerializer, ): @@ -579,7 +610,6 @@ class PartSerializer( 'description', 'full_name', 'image', - 'remote_image', 'existing_image', 'IPN', 'is_template', @@ -587,6 +617,7 @@ class PartSerializer( 'link', 'locked', 'minimum_stock', + 'maximum_stock', 'name', 'notes', 'parameters', @@ -637,7 +668,6 @@ class PartSerializer( - Allows us to optionally pass extra fields based on the query. """ - self.starred_parts = kwargs.pop('starred_parts', []) create = kwargs.pop('create', False) super().__init__(*args, **kwargs) @@ -649,7 +679,7 @@ class PartSerializer( # These fields are only used for the LIST API endpoint for f in self.skip_create_fields(): # Fields required for certain operations, but are not part of the model - if f in ['remote_image', 'existing_image']: + if f in ['existing_image']: continue self.fields.pop(f, None) @@ -705,6 +735,8 @@ class PartSerializer( ordering=part_filters.annotate_on_order_quantity(), in_stock=part_filters.annotate_total_stock(), allocated_to_sales_orders=part_filters.annotate_sales_order_allocations(), + # NOTE: for now, decided that allocations to Transfer Orders don't reduce available stock + # allocated_to_transfer_orders=part_filters.annotate_transfer_order_allocations(), allocated_to_build_orders=part_filters.annotate_build_order_allocations(), ) @@ -729,6 +761,8 @@ class PartSerializer( ExpressionWrapper( F('total_in_stock') - F('allocated_to_sales_orders') + # NOTE: for now, decided that allocations to Transfer Orders don't reduce available stock + # - F('allocated_to_transfer_orders'), - F('allocated_to_build_orders'), output_field=models.DecimalField(), ), @@ -738,6 +772,8 @@ class PartSerializer( ) # Annotate with the total 'required for builds' quantity + # NOTE: for now, we don't consider transfer orders for required quantities + # and they are assumed to operate on stock that already exists. queryset = queryset.annotate( required_for_build_orders=part_filters.annotate_build_order_requirements(), required_for_sales_orders=part_filters.annotate_sales_order_requirements(), @@ -753,31 +789,49 @@ class PartSerializer( def get_starred(self, part) -> bool: """Return "true" if the part is starred by the current user.""" - return part in self.starred_parts + if not self.request or not self.request.user: + return False + + # Cache the "starred_parts" list for the current user + if not hasattr(self, 'starred_parts'): + self.starred_parts = [ + star.part.pk for star in self.request.user.starred_parts.all() + ] + + return part.pk in self.starred_parts # Extra detail for the category - category_detail = enable_filter( - CategorySerializer( - source='category', many=False, read_only=True, allow_null=True - ), + category_detail = OptionalField( + serializer_class=CategorySerializer, + serializer_kwargs={ + 'source': 'category', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['category'], ) - category_path = enable_filter( - FilterableListField( - child=serializers.DictField(), - source='category.get_path', - read_only=True, - allow_null=True, - ), + category_path = OptionalField( + serializer_class=TreePathSerializer, + serializer_kwargs={ + 'source': 'category.get_path', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, filter_name='path_detail', prefetch_fields=['category'], ) - default_location_detail = enable_filter( - DefaultLocationSerializer( - source='default_location', many=False, read_only=True, allow_null=True - ), + default_location_detail = OptionalField( + serializer_class=DefaultLocationSerializer, + serializer_kwargs={ + 'source': 'default_location', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, filter_name='location_detail', prefetch_fields=['default_location'], ) @@ -871,6 +925,10 @@ class PartSerializer( required=False, label=_('Minimum Stock'), default=0 ) + maximum_stock = serializers.FloatField( + required=False, label=_('Maximum Stock'), default=0 + ) + image = InvenTree.serializers.InvenTreeImageSerializerField( required=False, allow_null=True ) @@ -883,25 +941,36 @@ class PartSerializer( ) # Pricing fields - pricing_min = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='pricing_data.overall_min', allow_null=True, read_only=True - ), - True, + pricing_min = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'pricing_data.overall_min', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) - pricing_max = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='pricing_data.overall_max', allow_null=True, read_only=True - ), - True, + + pricing_max = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'pricing_data.overall_max', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) - pricing_updated = enable_filter( - FilterableDateTimeField( - source='pricing_data.updated', allow_null=True, read_only=True - ), - True, + + pricing_updated = OptionalField( + serializer_class=serializers.DateTimeField, + serializer_kwargs={ + 'source': 'pricing_data.updated', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) @@ -909,11 +978,15 @@ class PartSerializer( tags = common.filters.enable_tags_filter() - price_breaks = enable_filter( - PartSalePriceSerializer( - source='salepricebreaks', many=True, read_only=True, allow_null=True - ), - False, + price_breaks = OptionalField( + serializer_class=PartSalePriceSerializer, + serializer_kwargs={ + 'source': 'salepricebreaks', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='price_breaks', prefetch_fields=['salepricebreaks'], ) @@ -1058,6 +1131,7 @@ class PartSerializer( part = self.instance data = self.validated_data + # TODO: Remove the existing_image field entirely! existing_image = data.pop('existing_image', None) if existing_image: @@ -1066,19 +1140,6 @@ class PartSerializer( part.image = img_path part.save() - # Check if an image was downloaded from a remote URL - remote_img = getattr(self, 'remote_image_file', None) - - if remote_img and part: - fmt = remote_img.format or 'PNG' - buffer = io.BytesIO() - remote_img.save(buffer, format=fmt) - - # Construct a simplified name for the image - filename = f'part_{part.pk}_image.{fmt.lower()}' - - part.image.save(filename, ContentFile(buffer.getvalue())) - return self.instance @@ -1249,10 +1310,15 @@ class PartStocktakeSerializer( label=_('Part Description'), ) - part_detail = enable_filter( - PartBriefSerializer( - source='part', read_only=True, allow_null=True, many=False, pricing=False - ), + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'read_only': True, + 'allow_null': True, + 'many': False, + 'pricing': False, + }, default_include=False, ) @@ -1577,7 +1643,7 @@ class BomItemSubstituteSerializer(InvenTree.serializers.InvenTreeModelSerializer model = BomItemSubstitute fields = ['pk', 'bom_item', 'part', 'part_detail'] - list_serializer_class = FilterableListSerializer + # list_serializer_class = FilterableListSerializer part_detail = PartBriefSerializer( source='part', read_only=True, many=False, pricing=False @@ -1592,7 +1658,7 @@ class BomItemSerializer( ): """Serializer for BomItem object.""" - import_exclude_fields = ['validated', 'substitutes'] + import_exclude_fields = ['quantity', 'validated', 'substitutes'] export_exclude_fields = ['substitutes'] @@ -1610,6 +1676,7 @@ class BomItemSerializer( 'part', 'sub_part', 'reference', + 'raw_amount', 'quantity', 'allow_variants', 'inherited', @@ -1644,7 +1711,13 @@ class BomItemSerializer( 'category_detail', ] - quantity = InvenTree.serializers.InvenTreeDecimalField(required=True) + raw_amount = serializers.CharField( + label=_('Amount'), + help_text=_('Amount required for this item (can include units)'), + required=False, + ) + + quantity = InvenTree.serializers.InvenTreeDecimalField(required=False) setup_quantity = InvenTree.serializers.InvenTreeDecimalField(required=False) @@ -1654,22 +1727,21 @@ class BomItemSerializer( required=False, allow_null=True ) - def validate_quantity(self, quantity): - """Perform validation for the BomItem quantity field.""" - if quantity <= 0: - raise serializers.ValidationError(_('Quantity must be greater than zero')) - - return quantity - part = serializers.PrimaryKeyRelatedField( queryset=Part.objects.filter(assembly=True), label=_('Assembly'), help_text=_('Select the parent assembly'), ) - substitutes = enable_filter( - BomItemSubstituteSerializer(many=True, read_only=True, allow_null=True), - False, + substitutes = OptionalField( + serializer_class=BomItemSubstituteSerializer, + serializer_kwargs={ + 'many': True, + 'read_only': True, + 'allow_null': True, + 'required': False, + }, + default_include=False, filter_name='substitutes', prefetch_fields=[ 'substitutes', @@ -1679,14 +1751,15 @@ class BomItemSerializer( ], ) - part_detail = enable_filter( - PartBriefSerializer( - source='part', - label=_('Assembly'), - many=False, - read_only=True, - allow_null=True, - ) + part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'label': _('Assembly'), + 'many': False, + 'read_only': True, + 'allow_null': True, + }, ) sub_part = serializers.PrimaryKeyRelatedField( @@ -1695,26 +1768,28 @@ class BomItemSerializer( help_text=_('Select the component part'), ) - sub_part_detail = enable_filter( - PartBriefSerializer( - source='sub_part', - label=_('Component'), - many=False, - read_only=True, - allow_null=True, - ), - True, + sub_part_detail = OptionalField( + serializer_class=PartBriefSerializer, + serializer_kwargs={ + 'source': 'sub_part', + 'label': _('Component'), + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, ) - category_detail = enable_filter( - CategorySerializer( - source='sub_part.category', - label=_('Category'), - many=False, - read_only=True, - allow_null=True, - ), - False, + category_detail = OptionalField( + serializer_class=CategorySerializer, + serializer_kwargs={ + 'source': 'sub_part.category', + 'label': _('Category'), + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, ) on_order = serializers.FloatField( @@ -1725,41 +1800,61 @@ class BomItemSerializer( label=_('In Production'), read_only=True, allow_null=True ) - can_build = enable_filter( - FilterableFloatField(label=_('Can Build'), read_only=True, allow_null=True), - True, + can_build = OptionalField( + serializer_class=serializers.FloatField, + serializer_kwargs={ + 'label': _('Can Build'), + 'read_only': True, + 'allow_null': True, + }, + default_include=True, ) # Cached pricing fields - pricing_min = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='sub_part.pricing_data.overall_min', allow_null=True, read_only=True - ), - True, + pricing_min = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'sub_part.pricing_data.overall_min', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) - pricing_max = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer( - source='sub_part.pricing_data.overall_max', allow_null=True, read_only=True - ), - True, + + pricing_max = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={ + 'source': 'sub_part.pricing_data.overall_max', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) - pricing_min_total = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer(allow_null=True, read_only=True), - True, + + pricing_min_total = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={'allow_null': True, 'read_only': True}, + default_include=True, filter_name='pricing', ) - pricing_max_total = enable_filter( - InvenTree.serializers.InvenTreeMoneySerializer(allow_null=True, read_only=True), - True, + + pricing_max_total = OptionalField( + serializer_class=InvenTree.serializers.InvenTreeMoneySerializer, + serializer_kwargs={'allow_null': True, 'read_only': True}, + default_include=True, filter_name='pricing', ) - pricing_updated = enable_filter( - FilterableDateTimeField( - source='sub_part.pricing_data.updated', allow_null=True, read_only=True - ), - True, + + pricing_updated = OptionalField( + serializer_class=serializers.DateTimeField, + serializer_kwargs={ + 'source': 'sub_part.pricing_data.updated', + 'allow_null': True, + 'read_only': True, + }, + default_include=True, filter_name='pricing', ) @@ -1773,6 +1868,27 @@ class BomItemSerializer( external_stock = serializers.FloatField(read_only=True, allow_null=True) + def validate(self, data): + """Validate the supplied data. + + Here, for legacy support, we intercept the 'quantity' field + (if the 'raw_amount' field is not provided) + """ + qty = data.pop('quantity', None) + + if 'raw_amount' not in data and qty is not None: + data['raw_amount'] = qty + + # Check the raw_amount field is valid (this will raise a ValidationError if not) + if raw_amount := data.get('raw_amount', None): + try: + # Check that the value is acceptable to the unit registry + InvenTree.conversion.convert_value(raw_amount) + except Exception: + raise ValidationError({'raw_amount': _('Invalid quantity format')}) + + return super().validate(data) + @staticmethod def annotate_queryset(queryset): """Annotate the BomItem queryset with extra information. @@ -1797,6 +1913,7 @@ class BomItemSerializer( 'sub_part__stock_items', 'sub_part__stock_items__allocations', 'sub_part__stock_items__sales_order_allocations', + 'sub_part__stock_items__transfer_order_allocations', ) # Annotate with the 'total pricing' information based on unit pricing and quantity @@ -1857,19 +1974,22 @@ class CategoryParameterTemplateSerializer( 'default_value', ] - template_detail = enable_filter( - common.serializers.ParameterTemplateSerializer( - source='template', many=False, read_only=True - ), - True, + template_detail = OptionalField( + serializer_class=common.serializers.ParameterTemplateSerializer, + serializer_kwargs={'source': 'template', 'many': False, 'read_only': True}, + default_include=True, prefetch_fields=['template'], ) - category_detail = enable_filter( - CategorySerializer( - source='category', many=False, read_only=True, allow_null=True - ), - True, + category_detail = OptionalField( + serializer_class=CategorySerializer, + serializer_kwargs={ + 'source': 'category', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, prefetch_fields=['category'], ) diff --git a/src/backend/InvenTree/part/stocktake.py b/src/backend/InvenTree/part/stocktake.py index 40bc857afd..a7b971680a 100644 --- a/src/backend/InvenTree/part/stocktake.py +++ b/src/backend/InvenTree/part/stocktake.py @@ -208,7 +208,7 @@ def perform_stocktake( if generate_entry: # Bulk-create PartStocktake entries - part_models.PartStocktake.objects.bulk_create(history_entries) + part_models.PartStocktake.objects.bulk_create(history_entries, batch_size=250) if report_output: # Save report data, and mark as complete diff --git a/src/backend/InvenTree/part/tasks.py b/src/backend/InvenTree/part/tasks.py index 87bc6a2f84..296604422b 100644 --- a/src/backend/InvenTree/part/tasks.py +++ b/src/backend/InvenTree/part/tasks.py @@ -12,6 +12,7 @@ from opentelemetry import trace import common.currency import common.notifications +import InvenTree.helpers import InvenTree.helpers_model from common.settings import get_global_setting from InvenTree.tasks import ( diff --git a/src/backend/InvenTree/part/test_api.py b/src/backend/InvenTree/part/test_api.py index 5db1e62f49..011c700884 100644 --- a/src/backend/InvenTree/part/test_api.py +++ b/src/backend/InvenTree/part/test_api.py @@ -3,7 +3,6 @@ import os from datetime import datetime from decimal import Decimal -from enum import IntEnum from random import randint from django.core.exceptions import ValidationError @@ -74,7 +73,6 @@ class PartImageTestMixin: {'image': img_file}, expected_code=200, ) - print(response.data) image_name = response.data['image'] self.assertTrue(image_name.startswith('/media/part_images/part_image')) return image_name @@ -111,7 +109,7 @@ class PartCategoryAPITest(InvenTreeAPITestCase): url = reverse('api-part-category-list') # star categories manually for tests as it is not possible with fixures - # because the current user is not fixured itself and throws an invalid + # because the current user is not fixtured itself and throws an invalid # foreign key constraint for pk in [3, 4]: PartCategory.objects.get(pk=pk).set_starred(self.user, True) @@ -277,7 +275,7 @@ class PartCategoryAPITest(InvenTreeAPITestCase): # There should not be any templates left at this point self.assertEqual(PartCategoryParameterTemplate.objects.count(), 0) - def test_bleach(self): + def test_sanitizer(self): """Test that the data cleaning functionality is working. This helps to protect against XSS injection @@ -332,116 +330,94 @@ class PartCategoryAPITest(InvenTreeAPITestCase): def test_category_delete(self): """Test category deletion with different parameters.""" - - class Target(IntEnum): - move_subcategories_to_parent_move_parts_to_parent = (0,) - move_subcategories_to_parent_delete_parts = (1,) - delete_subcategories_move_parts_to_parent = (2,) - delete_subcategories_delete_parts = (3,) - - for i in range(4): - delete_child_categories: bool = False - delete_parts: bool = False - - if i in ( - Target.move_subcategories_to_parent_delete_parts, - Target.delete_subcategories_delete_parts, - ): - delete_parts = True - if i in ( - Target.delete_subcategories_move_parts_to_parent, - Target.delete_subcategories_delete_parts, - ): - delete_child_categories = True - - # Create a parent category - parent_category = PartCategory.objects.create( - name='Parent category', - description='This is the parent category where the child categories and parts are moved to', - parent=None, - ) - - category_count_before = PartCategory.objects.count() - part_count_before = Part.objects.count() - - # Create a category to delete - cat_to_delete = PartCategory.objects.create( - name='Category to delete', - description='This is the category to be deleted', - parent=parent_category, - ) - - url = reverse('api-part-category-detail', kwargs={'pk': cat_to_delete.id}) - - parts = [] - # Create parts in the category to be deleted - for jj in range(3): - parts.append( - Part.objects.create( - name=f'Part xyz {i}_{jj}', - description='Child part of the deleted category', - category=cat_to_delete, - ) + for delete_child_categories in [False, True]: + for delete_parts in [False, True]: + # Create a parent category + parent_category = PartCategory.objects.create( + name='Parent category', + description='This is the parent category where the child categories and parts are moved to', + parent=None, ) - child_categories = [] - child_categories_parts = [] - # Create child categories under the category to be deleted - for ii in range(3): - child = PartCategory.objects.create( - name=f'Child parent_cat {i}_{ii}', - description='A child category of the deleted category', - parent=cat_to_delete, - ) - child_categories.append(child) + category_count_before = PartCategory.objects.count() - # Create parts in the child categories + # Create a category to delete + cat_to_delete = PartCategory.objects.create( + name='Category to delete', + description='This is the category to be deleted', + parent=parent_category, + ) + + url = reverse( + 'api-part-category-detail', kwargs={'pk': cat_to_delete.id} + ) + + parts = [] + # Create parts in the category to be deleted for jj in range(3): - child_categories_parts.append( + parts.append( Part.objects.create( - name=f'Part xyz {i}_{jj}_{ii}', - description='Child part in the child category of the deleted category', - category=child, + name=f'Part {"A" if delete_child_categories else "B"}{"C" if delete_parts else "D"}-{jj}', + description='Child part of the deleted category', + category=cat_to_delete, ) ) - # Delete the created category (sub categories and their parts will be moved under the parent) - params = {} - if delete_parts: - params['delete_parts'] = '1' - if delete_child_categories: - params['delete_child_categories'] = '1' - self.delete(url, params, expected_code=204) - - if delete_parts: - if i == Target.delete_subcategories_delete_parts: - # Check if all parts deleted - self.assertEqual(Part.objects.count(), part_count_before) - elif i == Target.move_subcategories_to_parent_delete_parts: - # Check if all parts deleted - self.assertEqual( - Part.objects.count(), - part_count_before + len(child_categories_parts), + child_categories = [] + child_categories_parts = [] + # Create child categories under the category to be deleted + for ii in range(3): + child = PartCategory.objects.create( + name=f'Child parent_cat {ii}', + description='A child category of the deleted category', + parent=cat_to_delete, ) - else: - # parts moved to the parent category - for part in parts: - part.refresh_from_db() - self.assertEqual(part.category, parent_category) + child_categories.append(child) - if delete_child_categories: - for part in child_categories_parts: + # Create parts in the child categories + for jj in range(3): + child_categories_parts.append( + Part.objects.create( + name=f'Part xyz {jj}_{ii}-{"E" if delete_child_categories else "F"}{"G" if delete_parts else "H"}', + description='Child part in the child category of the deleted category', + category=child, + ) + ) + + # Delete the created category (sub categories and their parts will be moved under the parent) + params = { + 'delete_parts': delete_parts, + 'delete_child_categories': delete_child_categories, + } + + self.delete(url, params, expected_code=204) + + if delete_parts: + # Check if all parts deleted + for p in parts: + with self.assertRaises(Part.DoesNotExist): + p.refresh_from_db() + else: + # parts moved to the parent category + for part in parts: part.refresh_from_db() self.assertEqual(part.category, parent_category) - if delete_child_categories: - # Check if all categories are deleted - self.assertEqual(PartCategory.objects.count(), category_count_before) - else: - # Check if all subcategories to parent moved to parent and all parts deleted - for child in child_categories: - child.refresh_from_db() - self.assertEqual(child.parent, parent_category) + if delete_child_categories: + for part in child_categories_parts: + part.refresh_from_db() + self.assertEqual(part.category, parent_category) + + if delete_child_categories: + # Check if all categories are deleted + self.assertEqual( + PartCategory.objects.count(), category_count_before + ) + else: + # Check if all subcategories to parent moved to parent and all parts deleted + for child in child_categories: + child.refresh_from_db() + self.assertEqual(child.parent, parent_category) def test_structural(self): """Test the effectiveness of structural categories. @@ -812,9 +788,14 @@ class PartAPITest(PartAPITestBase): # Children of PartCategory<1>, do not cascade response = self.get(url, {'parent': 1, 'cascade': 'false'}) - self.assertEqual(len(response.data), 3) + # Children of PartCategory<7>, with or without cascade + # Only 1 child in either case + for cascade in ['true', 'false']: + response = self.get(url, {'parent': 7, 'cascade': cascade}) + self.assertEqual(len(response.data), 1) + def test_add_categories(self): """Check that we can add categories.""" data = {'name': 'Animals', 'description': 'All animals go here'} @@ -1001,12 +982,14 @@ class PartAPITest(PartAPITestBase): sub_part.refresh_from_db() # Link the sub part to the assembly via a BOM - bom_item = BomItem.objects.create(part=assembly, sub_part=sub_part, quantity=10) + bom_item = BomItem.objects.create( + part=assembly, sub_part=sub_part, raw_amount='10', quantity=10 + ) filters = {'active': True, 'assembly': True, 'bom_valid': True} # Initially, there are no parts with a valid BOM - response = self.get(url, filters) + response = self.get(url, filters, expected_code=200) self.assertEqual(len(response.data), 0) @@ -1019,14 +1002,14 @@ class PartAPITest(PartAPITestBase): self.assertEqual(response.data[0]['pk'], assembly.pk) # Adjust the 'quantity' of the BOM item to make it invalid - bom_item.quantity = 15 + bom_item.set_quantity(15) bom_item.save() response = self.get(url, filters) self.assertEqual(len(response.data), 0) # Adjust it back again - should be valid again - bom_item.quantity = 10 + bom_item.set_quantity(10) bom_item.save() response = self.get(url, filters) @@ -1034,6 +1017,14 @@ class PartAPITest(PartAPITestBase): # Test the BOM validation API endpoint bom_url = reverse('api-part-bom-validate', kwargs={'pk': assembly.pk}) + + # Initially, we do not have the required role permissions + self.get(bom_url, expected_code=403) + + # Add required role + self.assignRole('bom.add') + + # Now we should be able to validate the BOM via the API data = self.get(bom_url, expected_code=200).data self.assertEqual(data['bom_validated'], True) @@ -1042,7 +1033,7 @@ class PartAPITest(PartAPITestBase): self.assertIsNotNone(data['bom_checked_date']) # Now, let's try to validate and invalidate the assembly BOM via the API - bom_item.quantity = 99 + bom_item.raw_amount = ' 99' bom_item.save() data = self.get(bom_url, expected_code=200).data @@ -1402,6 +1393,53 @@ class PartAPITest(PartAPITestBase): assert_subset=True, ) + def test_pricing_info(self): + """Test annotation of 'pricing' detail against a Part instance.""" + part = Part.objects.first() + url = reverse('api-part-detail', kwargs={'pk': part.pk}) + + pricing_fields = ['pricing_min', 'pricing_max', 'pricing_updated'] + + for included in [True, False]: + response = self.get(url, {'pricing': included}, expected_code=200) + + for field in pricing_fields: + if included: + self.assertIn(field, response.data) + else: + self.assertNotIn(field, response.data) + + def test_parameters_info(self): + """Test annotation of 'parameters' detail against a Part instance.""" + part = Part.objects.first() + url = reverse('api-part-detail', kwargs={'pk': part.pk}) + + for included in [True, False]: + response = self.get(url, {'parameters': included}, expected_code=200) + + if included: + self.assertIn('parameters', response.data) + else: + self.assertNotIn('parameters', response.data) + + def test_category_detail(self): + """Test annotation of 'category_detail' against a Part instance.""" + part = Part.objects.get(pk=1) + url = reverse('api-part-detail', kwargs={'pk': part.pk}) + + for included in [True, False]: + response = self.get(url, {'category_detail': included}, expected_code=200) + + if not included: + self.assertNotIn('category_detail', response.data) + continue + + self.assertIn('category_detail', response.data) + category = response.data['category_detail'] + + for field in ['name', 'description', 'structural']: + self.assertIn(field, category) + class PartCreationTests(PartAPITestBase): """Tests for creating new Part instances via the API.""" @@ -1644,7 +1682,7 @@ class PartCreationTests(PartAPITestBase): self.assertEqual(cat.parameter_templates.count(), 3) - # Creat a new Part, without copying category parameters + # Create a new Part, without copying category parameters data = self.post( reverse('api-part-list'), { @@ -1833,7 +1871,7 @@ class PartDetailTests(PartImageTestMixin, PartAPITestBase): # Part should not have an image! with self.assertRaises(ValueError): - print(p.image.file) + _x = p.image.file # Try to upload a non-image file test_path = get_testfolder_dir() / 'dummy_image' @@ -2314,7 +2352,7 @@ class PartAPIAggregationTest(InvenTreeAPITestCase): self.assertEqual(data['allocated_to_build_orders'], 0) self.assertEqual(data['allocated_to_sales_orders'], 0) - # The unallocated stock count should equal the 'in stock' coutn + # The unallocated stock count should equal the 'in stock' count in_stock = data['in_stock'] self.assertEqual(in_stock, 126) self.assertEqual(data['unallocated_stock'], in_stock) @@ -2588,6 +2626,58 @@ class PartAPIAggregationTest(InvenTreeAPITestCase): self.assertEqual(data['building'], 55) self.assertEqual(data['scheduled_to_build'], 32) + def test_low_stock(self): + """Test the 'low_stock' filter.""" + part = Part.objects.create( + name='Low Stock Part', + description='A part which is low on stock', + category=PartCategory.objects.get(pk=1), + minimum_stock=10, + ) + + response = self.get( + reverse('api-part-list'), {'low_stock': True}, expected_code=200 + ) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['pk'], part.pk) + + StockItem.objects.create(part=part, quantity=20) + + response = self.get( + reverse('api-part-list'), {'low_stock': True}, expected_code=200 + ) + + # No results should be returned, as the part is no longer low on stock + self.assertEqual(len(response.data), 0) + + def test_high_stock(self): + """Test the 'high_stock' filter.""" + part = Part.objects.create( + name='High Stock Part', + description='A part which is high on stock', + category=PartCategory.objects.get(pk=1), + ) + + StockItem.objects.create(part=part, quantity=100) + + response = self.get( + reverse('api-part-list'), {'high_stock': True}, expected_code=200 + ) + + self.assertEqual(len(response.data), 0) + + # Set a "maximum stock" threshold for the part + part.maximum_stock = 50 + part.save() + + response = self.get( + reverse('api-part-list'), {'high_stock': True}, expected_code=200 + ) + + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['pk'], part.pk) + class BomItemTest(InvenTreeAPITestCase): """Unit tests for the BomItem API.""" @@ -2703,8 +2793,28 @@ class BomItemTest(InvenTreeAPITestCase): def test_get_bom_detail(self): """Get the detail view for a single BomItem object.""" - url = reverse('api-bom-item-detail', kwargs={'pk': 3}) + from part.models import BomItemSubstitute + bom_item = BomItem.objects.get(pk=3) + + # Create some substitutes for this BomItem + substitute_parts = Part.objects.filter(component=True).exclude( + pk=bom_item.sub_part.pk + )[:3] + + for part in substitute_parts: + BomItemSubstitute.objects.create(bom_item=bom_item, part=part) + + self.assertEqual(bom_item.substitutes.count(), 3) + + url = reverse('api-bom-item-detail', kwargs={'pk': bom_item.pk}) + + # First, get without substitutes + response = self.get(url, expected_code=200) + + self.assertNotIn('substitutes', response.data) + + # Now, get with substitutes response = self.get(url, {'substitutes': True}, expected_code=200) expected_values = [ @@ -2717,6 +2827,7 @@ class BomItemTest(InvenTreeAPITestCase): 'rounding_multiple', 'pk', 'part', + 'raw_amount', 'quantity', 'reference', 'sub_part', @@ -2731,8 +2842,18 @@ class BomItemTest(InvenTreeAPITestCase): self.assertEqual(int(float(response.data['quantity'])), 25) + # Look at the substitutes data + subs = response.data['substitutes'] + + self.assertEqual(len(subs), 3) + + for sub in subs: + for field in ['pk', 'part', 'bom_item', 'part_detail']: + self.assertIn(field, sub) + # Increase the quantity data = response.data + del data['raw_amount'] data['quantity'] = 57 data['note'] = 'Added a note' @@ -2741,6 +2862,14 @@ class BomItemTest(InvenTreeAPITestCase): self.assertEqual(int(float(response.data['quantity'])), 57) self.assertEqual(response.data['note'], 'Added a note') + # Provide a conflicting "raw_amount" and "quantity" field + data['raw_amount'] = ' 123.45 ' + data['quantity'] = 99.99 + response = self.patch(url, data, expected_code=200) + + self.assertEqual(response.data['raw_amount'], '123.45') + self.assertAlmostEqual(response.data['quantity'], 123.45, places=2) + def test_output_options(self): """Test that various output options work as expected.""" self.run_output_test( @@ -2758,14 +2887,57 @@ class BomItemTest(InvenTreeAPITestCase): """Test that we can create a new BomItem via the API.""" url = reverse('api-bom-list') + # Test with legacy format (only the 'quantity' field is supplied) data = {'part': 100, 'sub_part': 4, 'quantity': 777} + response = self.post(url, data, expected_code=201) + self.assertEqual(response.data['raw_amount'], '777') + self.assertEqual(response.data['quantity'], 777) - self.post(url, data, expected_code=201) + # Test with the 'modern' format (accepts a raw_amount field) + data = {'part': 100, 'sub_part': 4, 'raw_amount': '123.45'} + response = self.post(url, data, expected_code=201) + self.assertEqual(response.data['raw_amount'], '123.45') + self.assertEqual(response.data['quantity'], 123.45) + + # First, let's assign some units to the sub_part + sub_part = Part.objects.get(pk=4) + sub_part.units = 'metres' + sub_part.save() + + # Test with a bunch of invalid 'raw_amount' values + for value in [ + '3 ampere', + '17 degrees', + '1 kg', + '-4', + 'yak', + '*****', + '$$$$$', + '', + ]: + data = {'part': 100, 'sub_part': 4, 'raw_amount': value} + self.post(url, data, expected_code=400) + + # Test with a bunch of valid 'raw_amount' values + test_values = [ + (5, 5), + ('3.14cm', 0.0314), + ('10 metres ', 10), + ('2 inches', 0.0508), + ('1/7', 0.142857), + ('14 ', 14), + ] + + for raw_amount, quantity in test_values: + data = {'part': 100, 'sub_part': 4, 'raw_amount': raw_amount} + response = self.post(url, data, expected_code=201) + self.assertEqual(response.data['raw_amount'], str(raw_amount).strip()) + self.assertAlmostEqual(response.data['quantity'], quantity, places=4) # Now try to create a BomItem which references itself - data['part'] = 100 - data['sub_part'] = 100 - self.post(url, data, expected_code=400) + data = {'part': 100, 'sub_part': 100, 'quantity': 1} + response = self.post(url, data, expected_code=400) + self.assertIn('(recursive)', str(response.data)) def test_variants(self): """Tests for BomItem use with variants.""" @@ -2833,6 +3005,12 @@ class BomItemTest(InvenTreeAPITestCase): # Count first, operate directly on Model countbefore = BomItemSubstitute.objects.count() + # Initially, the user does not have the required permissions + self.get(url, expected_code=403) + + # Assign the permission to view the substitute list + self.assignRole('bom.add') + # Now, make sure API returns the same count response = self.get(url, expected_code=200) self.assertEqual(len(response.data), countbefore) diff --git a/src/backend/InvenTree/part/test_bom_item.py b/src/backend/InvenTree/part/test_bom_item.py index 7c3e40fb70..13bebc5e3c 100644 --- a/src/backend/InvenTree/part/test_bom_item.py +++ b/src/backend/InvenTree/part/test_bom_item.py @@ -8,6 +8,7 @@ from django.test import TestCase import build.models import stock.models +from common.settings import set_global_setting from .models import BomItem, BomItemSubstitute, Part @@ -390,3 +391,121 @@ class BomItemTest(TestCase): # Delete the new BOM item bom_item.delete() + + def test_locked_assembly_locking_disabled(self): + """Test that a locked assembly is not enforced when PART_ENABLE_LOCKING is disabled.""" + assembly = Part.objects.create( + name='Assembly3', description='An assembly part', assembly=True + ) + sub_part = Part.objects.create( + name='SubPart2', description='A sub-part', component=True + ) + + bom_item = BomItem.objects.create(part=assembly, sub_part=sub_part, quantity=1) + + assembly.locked = True + assembly.save() + + # With locking enabled (default), editing is blocked + with self.assertRaises(django_exceptions.ValidationError): + bom_item.quantity = 5 + bom_item.save() + + # Disable locking globally — all BOM operations should now be allowed + set_global_setting('PART_ENABLE_LOCKING', False) + + bom_item.quantity = 5 + bom_item.save() + + BomItem.objects.create(part=assembly, sub_part=sub_part, quantity=2) + + bom_item.delete() + + # Re-enable for other tests + set_global_setting('PART_ENABLE_LOCKING', True) + + # Confirm locking is enforced again + bom_item2 = BomItem.objects.get(part=assembly, sub_part=sub_part, quantity=2) + with self.assertRaises(django_exceptions.ValidationError): + bom_item2.quantity = 99 + bom_item2.save() + + def test_bom_validated(self): + """Test for caching of 'bom_validated' property.""" + from part.tasks import validate_bom + + assembly = Part.objects.create( + name='Assembly1', description='An assembly part', assembly=True + ) + + assembly_2 = Part.objects.create( + name='Assembly2', description='An assembly part', assembly=True + ) + + def check(valid: bool = True): + """Helper function to check the BOM for this assembly.""" + nonlocal assembly + assembly.refresh_from_db() + self.assertEqual(assembly.bom_validated, valid) + + def validate(valid: bool = True): + """Helper function to validate the BOM for this assembly.""" + nonlocal assembly + validate_bom(assembly.pk, valid) + check(valid) + + check(valid=False) + validate() + + sub_part_1 = Part.objects.create( + name='SubPart1', description='A sub-part', component=True + ) + + sub_part_2 = Part.objects.create( + name='SubPart2', description='A sub-part', component=True + ) + + # Still valid at this stage - we have not made any changes to the BOM + check(valid=True) + + # Creating a *new* BOM item should invalidate the bom_validated cache + bom_item = BomItem.objects.create( + part=assembly, sub_part=sub_part_1, quantity=1 + ) + + check(valid=False) + + # Editing the BOM item should also invalidate the bom_validated cache + validate() + bom_item.set_quantity(2) + bom_item.save() + check(valid=False) + + # Editing the BOM item without changing any relevant fields should not invalidate the bom_validated cache + validate() + bom_item.description = 'This is a description' + bom_item.save() + check(valid=True) + + # Point the BOM item to a different component + validate() + bom_item.sub_part = sub_part_2 + bom_item.save() + check(valid=False) + + # Point the BOM to a different assembly + validate() + bom_item.part = assembly_2 + bom_item.save() + check(valid=False) + + # Check a partial restore - returning to previous state should re-validate + bom_item.part = assembly + bom_item.save() + check(valid=True) + + # Now, delete the BomItem entirely + bom_item.delete() + check(valid=False) + + self.assertIsNotNone(assembly.bom_checked_date) diff --git a/src/backend/InvenTree/part/test_category.py b/src/backend/InvenTree/part/test_category.py index dca64697da..6d3c7f7578 100644 --- a/src/backend/InvenTree/part/test_category.py +++ b/src/backend/InvenTree/part/test_category.py @@ -43,8 +43,8 @@ class CategoryTest(TestCase): self.assertTrue(self.electronics.has_children) self.assertTrue(self.mechanical.has_children) - self.assertEqual(len(self.electronics.children.all()), 3) - self.assertEqual(len(self.mechanical.children.all()), 1) + self.assertEqual(self.electronics.children.count(), 3) + self.assertEqual(self.mechanical.children.count(), 1) def test_unique_children(self): """Test the 'unique_children' functionality.""" diff --git a/src/backend/InvenTree/part/test_notification_stale.py b/src/backend/InvenTree/part/test_notification_stale.py index 86a4189a42..7999ab6ed5 100644 --- a/src/backend/InvenTree/part/test_notification_stale.py +++ b/src/backend/InvenTree/part/test_notification_stale.py @@ -50,8 +50,8 @@ class StaleStockNotificationTests(InvenTreeTestCase): set_global_setting('STOCK_STALE_DAYS', 7, self.user) # Clear notifications - NotificationEntry.objects.all().delete() # type: ignore[attr-defined] - NotificationMessage.objects.all().delete() # type: ignore[attr-defined] + NotificationEntry.objects.all().delete() + NotificationMessage.objects.all().delete() def create_stock_items_with_expiry(self): """Create stock items with various expiry dates for testing.""" @@ -101,7 +101,7 @@ class StaleStockNotificationTests(InvenTreeTestCase): part.tasks.notify_stale_stock(self.user, []) # No notifications should be created - self.assertEqual(NotificationMessage.objects.count(), 0) # type: ignore[attr-defined] + self.assertEqual(NotificationMessage.objects.count(), 0) def test_notify_stale_stock_single_item(self): """Test notify_stale_stock with a single stale item.""" diff --git a/src/backend/InvenTree/part/test_param.py b/src/backend/InvenTree/part/test_param.py index 76b3fb241b..41e6c3c4b0 100644 --- a/src/backend/InvenTree/part/test_param.py +++ b/src/backend/InvenTree/part/test_param.py @@ -6,6 +6,7 @@ from django.test import TestCase, TransactionTestCase from django.urls import reverse from common.models import InvenTreeSetting, Parameter, ParameterTemplate +from common.settings import set_global_setting from InvenTree.unit_test import InvenTreeAPITestCase from .models import Part, PartCategory, PartCategoryParameterTemplate @@ -141,6 +142,43 @@ class TestParams(TestCase): # And we can delete the parameter parameter.delete() + def test_locked_part_locking_disabled(self): + """Test that parameter restrictions are lifted when PART_ENABLE_LOCKING is disabled.""" + part = Part.objects.create( + name='Test Part Lock Override', + description='Part for testing global locking override', + category=PartCategory.objects.first(), + ) + + parameter = Parameter.objects.create( + content_object=part, template=ParameterTemplate.objects.first(), data='100' + ) + + part.locked = True + part.save() + + # With locking enabled (default), editing and deletion are blocked + with self.assertRaises(django_exceptions.ValidationError): + parameter.data = '200' + parameter.save() + + with self.assertRaises(django_exceptions.ValidationError): + parameter.delete() + + # Disable locking globally — parameter operations should now succeed + set_global_setting('PART_ENABLE_LOCKING', False) + + parameter.data = '200' + parameter.save() + self.assertEqual(parameter.data, '200') + + # Re-enable locking — editing should be blocked again + set_global_setting('PART_ENABLE_LOCKING', True) + + with self.assertRaises(django_exceptions.ValidationError): + parameter.data = '300' + parameter.save() + class TestCategoryTemplates(TransactionTestCase): """Test class for PartCategoryParameterTemplate model.""" diff --git a/src/backend/InvenTree/part/test_part.py b/src/backend/InvenTree/part/test_part.py index 8bb2ca37e4..05e58d225e 100644 --- a/src/backend/InvenTree/part/test_part.py +++ b/src/backend/InvenTree/part/test_part.py @@ -353,6 +353,28 @@ class PartTest(TestCase): part.delete() + def test_delete_locking_disabled(self): + """Test that a locked part can be deleted when PART_ENABLE_LOCKING is disabled.""" + part = Part.objects.create( + name='Locked Part Test', + description='Part for testing locking override', + active=False, + ) + + part.locked = True + part.save() + + # With locking enabled (default), deletion of a locked part raises an error + with self.assertRaises(ValidationError): + part.delete() + + # Disable locking globally — locked part should now be deletable + set_global_setting('PART_ENABLE_LOCKING', False) + part.delete() + + # Re-enable for other tests + set_global_setting('PART_ENABLE_LOCKING', True) + def test_revisions(self): """Test the 'revision' and 'revision_of' field.""" template = Part.objects.create( @@ -412,15 +434,11 @@ class PartTest(TestCase): name='Master Part', description='Master part (revision B)' ) - with self.assertRaises(ValidationError) as exc: - rev_b.revision_of = rev_a - rev_b.revision = 'B' - rev_b.save() - - self.assertIn( - 'Cannot make a revision of a part which is already a revision', - str(exc.exception), - ) + # Ensure we can make a revision of a revision + rev_b.revision_of = rev_a + rev_b.variant_of = template + rev_b.revision = 'B' + rev_b.save() rev_b.variant_of = template rev_b.revision_of = part diff --git a/src/backend/InvenTree/plugin/api.py b/src/backend/InvenTree/plugin/api.py index 91580062b3..400f0004df 100644 --- a/src/backend/InvenTree/plugin/api.py +++ b/src/backend/InvenTree/plugin/api.py @@ -210,6 +210,7 @@ class PluginInstall(CreateAPI): queryset = PluginConfig.objects.none() serializer_class = PluginSerializers.PluginConfigInstallSerializer + permission_classes = [InvenTree.permissions.IsSuperuserOrSuperScope] def create(self, request, *args, **kwargs): """Install a plugin via the API.""" @@ -316,13 +317,13 @@ def check_plugin( plugin_slug (str): Slug for plugin. plugin_pk (int): Primary key for plugin. + Returns: + InvenTreePlugin: The config object for the provided plugin. + Raises: NotFound: If plugin is not installed NotFound: If plugin is not correctly registered NotFound: If plugin is not active - - Returns: - InvenTreePlugin: The config object for the provided plugin. """ # Make sure that a plugin reference is specified if plugin_slug is None and plugin_pk is None: diff --git a/src/backend/InvenTree/plugin/base/barcodes/mixins.py b/src/backend/InvenTree/plugin/base/barcodes/mixins.py index 99c4661f57..c744cc04f2 100644 --- a/src/backend/InvenTree/plugin/base/barcodes/mixins.py +++ b/src/backend/InvenTree/plugin/base/barcodes/mixins.py @@ -60,7 +60,7 @@ class BarcodeMixin: """Does this plugin support barcode generation.""" try: # Attempt to call the generate method - self.generate(None) # type: ignore + self.generate(None) except NotImplementedError: # If a NotImplementedError is raised, then barcode generation is not supported return False diff --git a/src/backend/InvenTree/plugin/base/integration/AppMixin.py b/src/backend/InvenTree/plugin/base/integration/AppMixin.py index 532cc2578e..b3690afee1 100644 --- a/src/backend/InvenTree/plugin/base/integration/AppMixin.py +++ b/src/backend/InvenTree/plugin/base/integration/AppMixin.py @@ -113,9 +113,14 @@ class AppMixin: break # unregister the models (yes, models are just kept in multilevel dicts) + # Note: Django registers models under the app_label (app_name), + # not the full dotted plugin_path. For plugins with nested module + # paths (e.g. "myplugin.myplugin"), plugin_path != app_name, so + # using plugin_path here would look up the wrong key in the + # defaultdict and raise KeyError on .pop(). for model in models: # remove model from general registry - apps.all_models[plugin_path].pop(model) + apps.all_models[app_name].pop(model, None) # clear the registry for that app # so that the import trick will work on reloading the same plugin diff --git a/src/backend/InvenTree/plugin/base/integration/DataExport.py b/src/backend/InvenTree/plugin/base/integration/DataExport.py index 97d38ec493..15649e78dc 100644 --- a/src/backend/InvenTree/plugin/base/integration/DataExport.py +++ b/src/backend/InvenTree/plugin/base/integration/DataExport.py @@ -22,6 +22,9 @@ class DataExportMixin: ExportOptionsSerializer = None + # How many rows to fetch into memory at once when exporting data? + EXPORT_CHUNK_SIZE: int = 250 + class MixinMeta: """Meta options for this mixin.""" @@ -108,10 +111,29 @@ class DataExportMixin: Returns: The exported data (a list of dict objects) """ - # The default implementation simply serializes the queryset - return serializer_class( - queryset, many=True, exporting=True, context=serializer_context or {} - ).data + output.refresh_from_db() + N = queryset.count() + + rows = [] + + offset = 0 + + while offset < N: + chunk = queryset[offset : offset + self.EXPORT_CHUNK_SIZE] + + chunk_rows = serializer_class( + chunk, many=True, exporting=True, context=serializer_context or {} + ).data + + rows.extend(chunk_rows) + + offset += self.EXPORT_CHUNK_SIZE + + # Update the export progress + output.progress += len(chunk_rows) + output.save() + + return rows def get_export_options_serializer(self, **kwargs) -> serializers.Serializer | None: """Return a serializer class with dynamic export options for this plugin. diff --git a/src/backend/InvenTree/plugin/base/integration/ReportMixin.py b/src/backend/InvenTree/plugin/base/integration/ReportMixin.py index 77ee7e3dd2..d28ed395d2 100644 --- a/src/backend/InvenTree/plugin/base/integration/ReportMixin.py +++ b/src/backend/InvenTree/plugin/base/integration/ReportMixin.py @@ -24,7 +24,7 @@ class ReportMixin: super().__init__() self.add_mixin(PluginMixinEnum.REPORT, True, __class__) - def add_report_context(self, report_instance, model_instance, request, context): + def add_report_context(self, report_instance, model_instance, user, context): """Add extra context to the provided report instance. By default, this method does nothing. @@ -32,11 +32,11 @@ class ReportMixin: Args: report_instance: The report instance to add context to model_instance: The model instance which initiated the report generation - request: The request object which initiated the report generation + user: The user to associate with the generated report context: The context dictionary to add to """ - def add_label_context(self, label_instance, model_instance, request, context): + def add_label_context(self, label_instance, model_instance, user, context): """Add extra context to the provided label instance. By default, this method does nothing. @@ -44,18 +44,18 @@ class ReportMixin: Args: label_instance: The label instance to add context to model_instance: The model instance which initiated the label generation - request: The request object which initiated the label generation + user: The user to associate with the generated label context: The context dictionary to add to """ - def report_callback(self, template, instance, report, request, **kwargs): + def report_callback(self, template, instance, report, user, **kwargs): """Callback function called after a report is generated. Arguments: template: The ReportTemplate model instance: The instance of the target model report: The generated report object - request: The initiating request object + user: The user to associate with the generated report The default implementation does nothing. """ diff --git a/src/backend/InvenTree/plugin/base/integration/test_mixins.py b/src/backend/InvenTree/plugin/base/integration/test_mixins.py index a5495fb04f..4cf7e34714 100644 --- a/src/backend/InvenTree/plugin/base/integration/test_mixins.py +++ b/src/backend/InvenTree/plugin/base/integration/test_mixins.py @@ -1,5 +1,8 @@ """Unit tests for base mixins for plugins.""" +from collections import OrderedDict, defaultdict +from unittest.mock import MagicMock, patch + from django.conf import settings from django.test import TestCase from django.urls import include, path, re_path @@ -145,6 +148,56 @@ class AppMixinTest(BaseMixinDefinition, TestCase): """Test that the sample plugin registers in settings.""" self.assertIn('plugin.samples.integration', settings.INSTALLED_APPS) + def test_deactivate_nested_plugin_path(self): + """Test that _deactivate_mixin uses app_name (not plugin_path) for model deregistration. + + External plugins with nested module paths (e.g. "purchase_quotation.purchase_quotation") + have plugin_path != app_name. Django registers models under app_name (the last component), + so using the full plugin_path to look up apps.all_models would access the wrong key + in the defaultdict and raise KeyError on .pop(). + """ + # Simulate a nested plugin path like an external plugin installed via: + # entry_points={"inventree_plugins": [ + # "PurchaseQuotationPlugin = purchase_quotation.plugin:PurchaseQuotationPlugin" + # ]} + # where the package structure is purchase_quotation/purchase_quotation/ + nested_plugin_path = 'purchase_quotation.purchase_quotation' + app_name = 'purchase_quotation' # Django registers models under this + + # Set up a mock registry with the nested plugin path + mock_registry = MagicMock() + mock_registry.installed_apps = [nested_plugin_path] + + # Create a fake model + mock_model = MagicMock() + mock_model._meta.model_name = 'purchasequotation' + + # Create a mock app_config that returns our fake model + mock_app_config = MagicMock() + mock_app_config.get_models.return_value = [mock_model] + + # Set up apps.all_models with the model registered under app_name + # (this is how Django actually stores it) + fake_all_models = defaultdict(OrderedDict) + fake_all_models[app_name]['purchasequotation'] = mock_model + + with ( + patch( + 'plugin.base.integration.AppMixin.apps.get_app_config', + return_value=mock_app_config, + ), + patch('plugin.base.integration.AppMixin.apps.all_models', fake_all_models), + ): + # This should NOT raise KeyError - the fix ensures we use + # app_name (the last path component) instead of the full plugin_path + AppMixin._deactivate_mixin(mock_registry, force_reload=False) + + # Verify the model was removed from the registry + self.assertNotIn('purchasequotation', fake_all_models.get(app_name, {})) + # Verify the full nested path was NOT used as a key + # (defaultdict would have created an empty entry if accessed) + self.assertNotIn(nested_plugin_path, fake_all_models) + class NavigationMixinTest(BaseMixinDefinition, TestCase): """Tests for NavigationMixin.""" diff --git a/src/backend/InvenTree/plugin/base/label/mixins.py b/src/backend/InvenTree/plugin/base/label/mixins.py index deab3bf097..78182e343c 100644 --- a/src/backend/InvenTree/plugin/base/label/mixins.py +++ b/src/backend/InvenTree/plugin/base/label/mixins.py @@ -38,41 +38,51 @@ class LabelPrintingMixin: BLOCKING_PRINT = True - def render_to_pdf(self, label: LabelTemplate, instance, request, **kwargs): + def render_to_pdf( + self, label: LabelTemplate, instance, request, user=None, **kwargs + ): """Render this label to PDF format. Arguments: label: The LabelTemplate object to render against instance: The model instance to render - request: The HTTP request object which triggered this print job + request: The HTTP request object which triggered this print job (optional, may be None) + user: The user who triggered this print job (optional, may be None) """ try: - return label.render(instance, request) + return label.render(instance, request=request, user=user) except Exception: log_error('render_to_pdf', plugin=self.slug) raise ValidationError(_('Error rendering label to PDF')) - def render_to_html(self, label: LabelTemplate, instance, request, **kwargs): + def render_to_html( + self, label: LabelTemplate, instance, request, user=None, **kwargs + ): """Render this label to HTML format. Arguments: label: The LabelTemplate object to render against instance: The model instance to render - request: The HTTP request object which triggered this print job + request: The HTTP request object which triggered this print job (optional, may be None) + user: The user who triggered this print job (optional, may be None) """ try: - return label.render_as_string(instance, request) + return label.render_as_string(instance, request=request, user=user) except Exception: log_error('render_to_html', plugin=self.slug) raise ValidationError(_('Error rendering label to HTML')) - def render_to_png(self, label: LabelTemplate, instance, request=None, **kwargs): + def render_to_png( + self, label: LabelTemplate, instance, request=None, user=None, **kwargs + ): """Render this label to PNG format. Arguments: label: The LabelTemplate object to render against instance: The model instance to render - request: The HTTP request object which triggered this print job + request: The HTTP request object which triggered this print job (optional, may be None) + user: The user who triggered this print job (optional, may be None) + Keyword Arguments: pdf_data: The raw PDF data of the rendered label (if already rendered) dpi: The DPI to use for the PNG rendering @@ -85,7 +95,7 @@ class LabelPrintingMixin: pdf_data = kwargs.get('pdf_data') if not pdf_data: - pdf_data = self.render_to_pdf(label, instance, request, **kwargs) + pdf_data = self.render_to_pdf(label, instance, request, user=user, **kwargs) pdf2image_kwargs = { 'dpi': kwargs.get('dpi', InvenTreeSetting.get_setting('LABEL_DPI', 300)), @@ -128,10 +138,12 @@ class LabelPrintingMixin: The default implementation simply calls print_label() for each label, producing multiple single label output "jobs" but this can be overridden by the particular plugin. """ - try: - user = request.user - except AttributeError: - user = None + # Extract user information, in decreasing order of preference + user = ( + kwargs.pop('user', None) + or getattr(request, 'user', None) + or getattr(output, 'user', None) + ) # Initial state for the output print job output.progress = 0 @@ -145,11 +157,11 @@ class LabelPrintingMixin: # Generate a label output for each provided item for item in items: - context = label.get_context(item, request) + context = label.get_context(item, request, user=user) filename = label.generate_filename(context) - pdf_data = self.render_to_pdf(label, item, request, **kwargs) + pdf_data = self.render_to_pdf(label, item, request, user=user, **kwargs) png_file = self.render_to_png( - label, item, request, pdf_data=pdf_data, **kwargs + label, item, request, pdf_data=pdf_data, user=user, **kwargs ) print_args = { diff --git a/src/backend/InvenTree/plugin/base/supplier/mixins.py b/src/backend/InvenTree/plugin/base/supplier/mixins.py index 27c35d4d47..56e924f061 100644 --- a/src/backend/InvenTree/plugin/base/supplier/mixins.py +++ b/src/backend/InvenTree/plugin/base/supplier/mixins.py @@ -161,7 +161,7 @@ class SupplierMixin(SettingsMixin, Generic[PartData]): # assign parent_part to root_part if root_part has no variant of already if root_part and not root_part.is_template and not root_part.variant_of: - root_part.variant_of = parent_part # type: ignore + root_part.variant_of = parent_part root_part.save() return parent_part diff --git a/src/backend/InvenTree/plugin/base/ui/mixins.py b/src/backend/InvenTree/plugin/base/ui/mixins.py index cbffd1fb9a..9aa4a67edd 100644 --- a/src/backend/InvenTree/plugin/base/ui/mixins.py +++ b/src/backend/InvenTree/plugin/base/ui/mixins.py @@ -21,6 +21,7 @@ FeatureType = Literal[ 'template_editor', # Custom template editor 'template_preview', # Custom template preview 'navigation', # Custom navigation items + 'primary_action', # Custom primary action buttons ] @@ -83,7 +84,7 @@ class UserInterfaceMixin: def __init__(self): """Register mixin.""" super().__init__() - self.add_mixin(PluginMixinEnum.USER_INTERFACE, True, __class__) # type: ignore + self.add_mixin(PluginMixinEnum.USER_INTERFACE, True, __class__) def get_ui_features( self, feature_type: FeatureType, context: dict, request: Request, **kwargs @@ -106,6 +107,7 @@ class UserInterfaceMixin: 'panel': self.get_ui_panels, 'template_editor': self.get_ui_template_editors, 'template_preview': self.get_ui_template_previews, + 'primary_action': self.get_ui_primary_actions, } if feature_type in feature_map: @@ -203,3 +205,29 @@ class UserInterfaceMixin: """ # Default implementation returns an empty list return [] + + def get_ui_primary_actions( + self, request: Request, context: dict, **kwargs + ) -> list[UIFeature]: + """Return a list of custom primary action buttons to be injected into the UI. + + Args: + request: HTTPRequest object (including user information) + context: Additional context data provided by the UI (query parameters) + + Returns: + list: A list of custom primary action buttons to be injected into the UI + """ + # Sample code to render conditional primary action button based on context + # items = [] + # if self.my_assert_function(context): + # items.append({ + # 'key': 'sample-primary-action', + # 'title': 'Sample Primary Action', + # 'icon': 'ti:plus:outline', + # 'options': {'url': '/core/sample-primary-action/', 'color': 'orange'}, + # }) + # return items + + # Default implementation returns an empty list + return [] diff --git a/src/backend/InvenTree/plugin/base/ui/tests.py b/src/backend/InvenTree/plugin/base/ui/tests.py index e38e64a856..0a4a94977b 100644 --- a/src/backend/InvenTree/plugin/base/ui/tests.py +++ b/src/backend/InvenTree/plugin/base/ui/tests.py @@ -233,3 +233,13 @@ class UserInterfaceMixinTests(InvenTreeAPITestCase): self.assertEqual(response.data[0]['plugin_name'], 'sampleui') self.assertEqual(response.data[0]['key'], 'sample-nav-item') self.assertEqual(response.data[0]['title'], 'Sample Nav Item') + + def test_ui_primary_actions(self): + """Test that the sample UI plugin provides custom primary actions.""" + response = self.get( + reverse('api-plugin-ui-feature-list', kwargs={'feature': 'primary_action'}) + ) + self.assertEqual(1, len(response.data)) + self.assertEqual(response.data[0]['plugin_name'], 'sampleui') + self.assertEqual(response.data[0]['key'], 'sample-primary-action') + self.assertEqual(response.data[0]['title'], 'Sample Primary Action') diff --git a/src/backend/InvenTree/plugin/broken/broken_file.py b/src/backend/InvenTree/plugin/broken/broken_file.py index 83437025cf..f56932e876 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 # type: ignore[unresolved-reference] +aaa = bb # noqa: F821 diff --git a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py index a35df5739d..2f7d7b11ca 100644 --- a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py +++ b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py @@ -55,7 +55,7 @@ class InvenTreeUINotifications(NotificationMixin, InvenTreePlugin): ) ) - NotificationMessage.objects.bulk_create(entries) + NotificationMessage.objects.bulk_create(entries, batch_size=250) return True diff --git a/src/backend/InvenTree/plugin/builtin/labels/inventree_label.py b/src/backend/InvenTree/plugin/builtin/labels/inventree_label.py index 28158952a7..7654043ebd 100644 --- a/src/backend/InvenTree/plugin/builtin/labels/inventree_label.py +++ b/src/backend/InvenTree/plugin/builtin/labels/inventree_label.py @@ -20,6 +20,7 @@ class InvenTreeLabelPlugin(LabelPrintingMixin, SettingsMixin, InvenTreePlugin): """ NAME = 'InvenTreeLabel' + SLUG = 'inventreelabel' TITLE = _('InvenTree PDF label printer') DESCRIPTION = _('Provides native support for printing PDF labels') VERSION = '1.1.0' diff --git a/src/backend/InvenTree/plugin/installer.py b/src/backend/InvenTree/plugin/installer.py index b1fb2de03f..acf6584a8d 100644 --- a/src/backend/InvenTree/plugin/installer.py +++ b/src/backend/InvenTree/plugin/installer.py @@ -236,8 +236,8 @@ def install_plugin(url=None, packagename=None, user=None, version=None): user: Optional user performing the installation version: Optional version specifier """ - if user and not user.is_staff: - raise ValidationError(_('Only staff users can administer plugins')) + if user and not user.is_superuser: + raise ValidationError(_('Only superuser accounts can administer plugins')) if settings.PLUGINS_INSTALL_DISABLED: raise ValidationError(_('Plugin installation is disabled')) @@ -269,6 +269,13 @@ def install_plugin(url=None, packagename=None, user=None, version=None): if version: full_pkg = f'{full_pkg}=={version}' + if not full_pkg: + 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 ';&|`$()'): + raise ValidationError(_('Invalid characters in package name or URL')) + install_name.append(full_pkg) ret = {} @@ -333,6 +340,9 @@ def uninstall_plugin(cfg: plugin.models.PluginConfig, user=None, delete_config=T """ from plugin.registry import registry + if user and not user.is_superuser: + raise ValidationError(_('Only superuser accounts can administer plugins')) + if settings.PLUGINS_INSTALL_DISABLED: raise ValidationError(_('Plugin uninstalling is disabled')) diff --git a/src/backend/InvenTree/plugin/plugin.py b/src/backend/InvenTree/plugin/plugin.py index 558ca3edf8..1e9518cc99 100644 --- a/src/backend/InvenTree/plugin/plugin.py +++ b/src/backend/InvenTree/plugin/plugin.py @@ -1,14 +1,16 @@ """Base Class for InvenTree plugins.""" import inspect +import json +import re import warnings from datetime import datetime -from distutils.sysconfig import get_python_lib # type: ignore[import] from importlib.metadata import PackageNotFoundError, metadata from pathlib import Path from typing import Optional from django.conf import settings +from django.contrib.staticfiles.storage import StaticFilesStorage from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ @@ -92,16 +94,16 @@ class MetaBase: TITLE = None @mark_final - def get_meta_value(self, key: str, old_key: Optional[str] = None, __default=None): + def get_meta_value(self, key: str, old_key: Optional[str] = None, default=None): """Reference a meta item with a key. Args: key (str): key for the value old_key (str, optional): deprecated key - will throw warning - __default (optional): Value if nothing with key can be found. Defaults to None. + default (optional): Value if nothing with key can be found. Defaults to None. Returns: - Value referenced with key, old_key or __default if set and not value found + Value referenced with key, old_key or default if set and not value found """ value = getattr(self, key, None) @@ -117,9 +119,9 @@ class MetaBase: stacklevel=2, ) - # Use __default if still nothing set - if (value is None) and __default: - return __default + # Use default if still nothing set + if value is None and default is not None: + return default return value @mark_final @@ -525,6 +527,8 @@ 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')) return bool(len(dist_info) == 1) @@ -578,35 +582,119 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase): # endregion + def get_static_path(self) -> list[str]: + """Return the path components to the plugin's static files.""" + return ['plugins', self.slug] + + def hashed_file_lookup(self, *args) -> str | None: + """Find a hashed version of the given file, if it exists. + + This is used to support cache busting for static files. + + Arguments: + *args: Path components to the static file (e.g. 'js', 'admin.js') + + Returns: + str: Path to the hashed version of the file if it exists, else None + """ + storage = StaticFilesStorage() + + # First, try to find a manifest file which maps original filenames to hashed filenames + # We only support vite manifest files - as generated by the plugin creator framework + manifest_file = str(Path(*self.get_static_path(), '.vite', 'manifest.json')) + + if not storage.exists(manifest_file): + return None + + # Read the contents of the manifest file + try: + with storage.open(manifest_file) as f: + manifest = json.load(f) + except json.JSONDecodeError: + logger.error(f"Failed to parse manifest file for plugin '{self.SLUG}'") + return None + + # Find the entry associated with the requested file + # Remove the file extension, as the manifest may contain hashed files with different extensions (e.g. .js, .css) + filename = str(args[-1] or '').split('.')[0] + pattern = re.compile(rf'{re.escape(filename)}\.(js|jsx|tsx)') + + for key, value in manifest.items(): + if re.search(pattern, key): + return value.get('file') + + return None + @mark_final - def plugin_static_file(self, *args) -> str: + def plugin_static_file( + self, *args, check_exists: bool = True, check_hash: bool = True + ) -> str: """Construct a path to a static file within the plugin directory. + Arguments: + *args: Path components to the static file (e.g. 'js', 'admin.js') + check_exists: If True, will check if the file actually exists on disk + check_hash: If True, will fallback to checking if the file has a hash in its name (for cache busting) + - This will return a URL can be used to access the static file - The path is constructed using the STATIC_URL setting and the plugin slug - Note: If the plugin is selected for "development" mode, the path will point to a vite server URL + Hash Checking: + + - Plugins may distribute static files with a hash in the filename for cache busting purposes (e.g. 'file-abc123.js'). + - If available, this file is priorities, and the non-hashed version is ignored. + - If no hashed file is available, the non-hashed version will be used (if it exists). + - If check_hash is False, the non-hashed version of the file will be used (even if a hashed version exists). + """ - import os - from django.conf import settings + from django.contrib.staticfiles.storage import StaticFilesStorage + # If the plugin is selected for development mode, use the development host + # This allows the plugin developer to run a local vite server and have the plugin load files directly from that server if ( settings.DEBUG and settings.PLUGIN_DEV_HOST and settings.PLUGIN_DEV_SLUG and self.SLUG == settings.PLUGIN_DEV_SLUG ): - # If the plugin is selected for development mode, use the development host pathname = '/'.join(list(args)) url = f'{settings.PLUGIN_DEV_HOST}/src/{pathname}' url = url.replace('.js', '.tsx') - else: - # Otherwise, construct the URL using the STATIC_URL setting - url = os.path.join(settings.STATIC_URL, 'plugins', self.SLUG, *args) + return url - if not url.startswith('/'): - url = '/' + url + storage = StaticFilesStorage() + + file_name = args[-1] or '' + + # The file may be specified with a function, e.g. 'file.js:renderFunction' + if ':' in file_name: + file_name, function_name = file_name.split(':')[:2] + else: + function_name = '' + + # Determine the preceding path to the file (if any) + file_path = args[:-1] + + # If enabled, check for a hashed version of the file + if check_hash: + file_name = self.hashed_file_lookup(*file_path, file_name) or file_name + + full_path = str(Path(*self.get_static_path(), *file_path, file_name)) + + if check_exists: + if not storage.exists(full_path): + logger.error( + f"Static file not found for plugin '{self.SLUG}': {full_path}" + ) + + # Resolve the URL to the static file + url = storage.url(full_path) + + # Re-append the function name (if provided) + if function_name: + url += f':{function_name}' return url diff --git a/src/backend/InvenTree/plugin/registry.py b/src/backend/InvenTree/plugin/registry.py index 47f43d997f..382a973906 100644 --- a/src/backend/InvenTree/plugin/registry.py +++ b/src/backend/InvenTree/plugin/registry.py @@ -222,13 +222,18 @@ class PluginsRegistry: import InvenTree.ready from plugin.models import PluginConfig - if InvenTree.ready.isImportingData(): - return None + # 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() + ) try: cfg = PluginConfig.objects.filter(key=slug).first() - if not cfg: + if not cfg and can_create: logger.debug( "get_plugin_config: Creating new PluginConfig for '%s'", slug ) @@ -781,9 +786,9 @@ class PluginsRegistry: f"Plugin '{p}' is not compatible with the current InvenTree version {v}" ) if v := plg_i.MIN_VERSION: - _msg += _(f'Plugin requires at least version {v}') # type: ignore[unsupported-operator] + _msg += _(f'Plugin requires at least version {v}') # ty:ignore[unsupported-operator] if v := plg_i.MAX_VERSION: - _msg += _(f'Plugin requires at most version {v}') # type: ignore[unsupported-operator] + _msg += _(f'Plugin requires at most version {v}') # ty:ignore[unsupported-operator] # Log to error stack log_registry_error(_msg, reference=f'{p}:init_plugin') else: diff --git a/src/backend/InvenTree/plugin/samples/integration/test_validation_sample.py b/src/backend/InvenTree/plugin/samples/integration/test_validation_sample.py index b0883344db..f6f7f0fbb1 100644 --- a/src/backend/InvenTree/plugin/samples/integration/test_validation_sample.py +++ b/src/backend/InvenTree/plugin/samples/integration/test_validation_sample.py @@ -49,7 +49,7 @@ class SampleValidatorPluginTest(InvenTreeAPITestCase, InvenTreeTestCase): self.assembly.refresh_from_db() self.bom_item = part.models.BomItem.objects.create( - part=self.assembly, sub_part=self.part, quantity=1 + part=self.assembly, sub_part=self.part, raw_amount=1, quantity=1 ) self.enable_plugin(False) @@ -75,14 +75,14 @@ class SampleValidatorPluginTest(InvenTreeAPITestCase, InvenTreeTestCase): plg.set_setting('BOM_ITEM_INTEGER', True) - self.bom_item.quantity = 3.14159 + self.bom_item.raw_amount = 3.14159 with self.assertRaises(ValidationError): self.bom_item.save() # Now, disable the plugin setting plg.set_setting('BOM_ITEM_INTEGER', False) - self.bom_item.quantity = 3.14159 + self.bom_item.set_quantity(3.14159) self.bom_item.save() # Test that we *cannot* set a part description to a shorter value diff --git a/src/backend/InvenTree/plugin/samples/integration/user_interface_sample.py b/src/backend/InvenTree/plugin/samples/integration/user_interface_sample.py index 70c47f220a..09bdbb7f37 100644 --- a/src/backend/InvenTree/plugin/samples/integration/user_interface_sample.py +++ b/src/backend/InvenTree/plugin/samples/integration/user_interface_sample.py @@ -226,6 +226,17 @@ class SampleUserInterfacePlugin(SettingsMixin, UserInterfaceMixin, InvenTreePlug } ] + def get_ui_primary_actions(self, request, context, **kwargs): + """Return a list of custom primary action buttons.""" + return [ + { + 'key': 'sample-primary-action', + 'title': 'Sample Primary Action', + 'icon': 'ti:plus:outline', + 'options': {'url': '/core/sample-primary-action/', 'color': 'orange'}, + } + ] + def get_admin_context(self) -> dict: """Return custom context data which can be rendered in the admin panel.""" return {'apple': 'banana', 'foo': 'bar', 'hello': 'world'} diff --git a/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py b/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py index 9fe6d8ea00..4ea7d761b8 100644 --- a/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py +++ b/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py @@ -1,5 +1,7 @@ """Sample supplier plugin.""" +from django.conf import settings + from company.models import Company, ManufacturerPart, SupplierPart, SupplierPriceBreak from part.models import Part from plugin.mixins import SupplierMixin, supplier @@ -13,7 +15,16 @@ class SampleSupplierPlugin(SupplierMixin, InvenTreePlugin): SLUG = 'samplesupplier' TITLE = 'My sample supplier plugin' - VERSION = '0.0.1' + VERSION = '0.0.2' + + SETTINGS = { + 'DOWNLOAD_IMAGES': { + 'name': 'Download part images', + 'description': 'Enable downloading of part images during import (not recommended during testing)', + 'validator': bool, + 'default': False, + } + } def __init__(self): """Initialize the sample supplier plugin.""" @@ -108,7 +119,12 @@ class SampleSupplierPlugin(SupplierMixin, InvenTreePlugin): # If the part was created, set additional fields if created: - if data['image_url']: + # Prevent downloading images during testing, as this can lead to unreliable tests + if ( + data['image_url'] + and not settings.TESTING + and self.get_setting('DOWNLOAD_IMAGES') + ): file, fmt = self.download_image(data['image_url']) filename = f'part_{part.pk}_image.{fmt.lower()}' part.image.save(filename, file) @@ -136,7 +152,7 @@ class SampleSupplierPlugin(SupplierMixin, InvenTreePlugin): # after the template part was created, we need to refresh the part from the db because its tree id may have changed # which results in an error if saved directly part.refresh_from_db() - part.variant_of = parent_part # type: ignore + part.variant_of = parent_part part.save() return part diff --git a/src/backend/InvenTree/plugin/serializers.py b/src/backend/InvenTree/plugin/serializers.py index 5fbff385b4..b12d0d3590 100644 --- a/src/backend/InvenTree/plugin/serializers.py +++ b/src/backend/InvenTree/plugin/serializers.py @@ -165,6 +165,9 @@ class PluginConfigInstallSerializer(serializers.Serializer): version = data.get('version', None) user = self.context['request'].user + if not user or not user.is_superuser: + raise ValidationError(_('Only superuser accounts can administer plugins')) + return install_plugin( url=url, packagename=packagename, version=version, user=user ) @@ -266,10 +269,13 @@ class PluginUninstallSerializer(serializers.Serializer): """Uninstall the specified plugin.""" from plugin.installer import uninstall_plugin + user = self.context['request'].user + + if not user or not user.is_superuser: + raise ValidationError(_('Only superuser accounts can administer plugins')) + return uninstall_plugin( - instance, - user=self.context['request'].user, - delete_config=validated_data.get('delete_config', True), + instance, user=user, delete_config=validated_data.get('delete_config', True) ) diff --git a/src/backend/InvenTree/plugin/test_api.py b/src/backend/InvenTree/plugin/test_api.py index ca6c312670..820c5c96fa 100644 --- a/src/backend/InvenTree/plugin/test_api.py +++ b/src/backend/InvenTree/plugin/test_api.py @@ -63,6 +63,21 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase): """Test the plugin install command.""" url = reverse('api-plugin-install') + # Requires superuser permissions + self.user.is_superuser = False + self.user.save() + + self.post( + url, + {'confirm': True, 'packagename': self.PKG_NAME}, + expected_code=403, + max_query_time=30, + ) + + # Provide superuser permissions + self.user.is_superuser = True + self.user.save() + # invalid package name data = self.post( url, @@ -209,7 +224,7 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase): test_plg.refresh_from_db() self.assertTrue(test_plg.is_active()) - def test_pluginCfg_delete(self): + def test_plugin_config_delete(self): """Test deleting a config.""" test_plg = self.plugin_confs.first() assert test_plg is not None diff --git a/src/backend/InvenTree/plugin/test_plugin.py b/src/backend/InvenTree/plugin/test_plugin.py index cdabd46477..c918eadc3d 100644 --- a/src/backend/InvenTree/plugin/test_plugin.py +++ b/src/backend/InvenTree/plugin/test_plugin.py @@ -11,11 +11,14 @@ from typing import Optional from unittest import mock from unittest.mock import patch +from django.contrib.auth.models import User +from django.core.exceptions import ValidationError from django.test import TestCase, override_settings import plugin.templatetags.plugin_extras as plugin_tags from InvenTree.unit_test import PluginRegistryMixin, TestQueryMixin from plugin import InvenTreePlugin, PluginMixinEnum +from plugin.installer import install_plugin from plugin.registry import registry from plugin.samples.integration.another_sample import ( NoIntegrationPlugin, @@ -209,6 +212,54 @@ class InvenTreePluginTests(TestCase): if plug: self.assertEqual(plug.is_active(), False) + def test_plugin_static_file_lookup(self): + """Test that the plugin static file lookup works as expected.""" + from django.contrib.staticfiles.storage import StaticFilesStorage + from django.core.files.base import ContentFile + + # Create a sample plugin with a known static file + class StaticFilePlugin(InvenTreePlugin): + NAME = 'StaticFilePlugin' + SLUG = 'static-file-test' + + def get_static_file_url(self, file_name): + return self.get_plugin_static_file(file_name) + + plugin = StaticFilePlugin() + storage = StaticFilesStorage() + + # A simple test to ensure the path is correctly resolved + self.assertEqual( + plugin.plugin_static_file( + 'sample.js', check_exists=False, check_hash=False + ), + storage.url('plugins/static-file-test/sample.js'), + ) + + manifest_path = 'plugins/static-file-test/.vite/manifest.json' + + manifest_data = textwrap.dedent("""{ + "src/sample.js": { + "file": "sample.123456.js", + "name": "sample", + "src": "src/sample.js", + "isEntry": true + } + }""") + + # A more comprehensive test - to find a hashed version of the file + # Note: This requires a manifest file to be present - let's create one + if not storage.exists(manifest_path): + storage.save(manifest_path, content=ContentFile(manifest_data)) + + lookup = plugin.plugin_static_file( + 'sample.js', check_exists=False, check_hash=True + ) + + self.assertEqual( + lookup, storage.url('plugins/static-file-test/sample.123456.js') + ) + class RegistryTests(TestQueryMixin, PluginRegistryMixin, TestCase): """Tests for registry loading methods.""" @@ -254,7 +305,7 @@ class RegistryTests(TestQueryMixin, PluginRegistryMixin, TestCase): def test_folder_loading(self): """Test that plugins in folders outside of BASE_DIR get loaded.""" # Run in temporary directory -> always a new random name - with tempfile.TemporaryDirectory() as tmp: # type: ignore[no-matching-overload] + with tempfile.TemporaryDirectory() as tmp: # Fill directory with sample data new_dir = Path(tmp).joinpath('mock') shutil.copytree(self.mockDir(), new_dir) @@ -278,6 +329,9 @@ class RegistryTests(TestQueryMixin, PluginRegistryMixin, TestCase): def test_broken_samples(self): """Test that the broken samples trigger reloads.""" + # Reset the registry to a known state + registry.errors = {} + # In the base setup there are no errors self.assertEqual(len(registry.errors), 0) @@ -638,3 +692,40 @@ class RegistryTests(TestQueryMixin, PluginRegistryMixin, TestCase): self.assertTrue(cfg.is_builtin()) self.assertFalse(cfg.is_package()) self.assertFalse(cfg.is_sample()) + + +class InstallerTests(TestCase): + """Tests for the plugin installer code.""" + + def test_plugin_install_errors(self): + """Test error handling for plugin installation.""" + # No data provided + with self.assertRaises(ValidationError) as e: + install_plugin() + + self.assertIn( + 'No package name or URL provided for installation', str(e.exception) + ) + + # Invalid package name + for pkg in [ + 'invalid;name', + 'invalid&name', + 'invalid|name', + 'invalid`name', + 'invalid$(name)', + ]: + with self.assertRaises(ValidationError) as e: + install_plugin(packagename=pkg) + + self.assertIn('Invalid characters in package name or URL', str(e.exception)) + + # Non superuser account + user = User.objects.create(username='my-user', is_superuser=False) + + with self.assertRaises(ValidationError) as e: + install_plugin(user=user, packagename='some-package') + + self.assertIn( + 'Only superuser accounts can administer plugins', str(e.exception) + ) diff --git a/src/backend/InvenTree/report/api.py b/src/backend/InvenTree/report/api.py index d9ad6ab1cb..9e62735c10 100644 --- a/src/backend/InvenTree/report/api.py +++ b/src/backend/InvenTree/report/api.py @@ -214,6 +214,7 @@ class LabelPrint(GenericAPIView): template.pk, [item.pk for item in items_to_print], output.pk, + user.pk if user else None, plugin.slug, options=(plugin_serializer.data if plugin_serializer else {}), ) @@ -223,23 +224,27 @@ class LabelPrint(GenericAPIView): return Response(DataOutputSerializer(output).data, status=201) -class LabelTemplateList(TemplatePermissionMixin, ListCreateAPI): +class LabelTemplateMixin: + """Mixin class for label template API views.""" + + queryset = report.models.LabelTemplate.objects.all().prefetch_related('updated_by') + serializer_class = report.serializers.LabelTemplateSerializer + + +class LabelTemplateList(TemplatePermissionMixin, LabelTemplateMixin, ListCreateAPI): """API endpoint for viewing list of LabelTemplate objects.""" - queryset = report.models.LabelTemplate.objects.all() - serializer_class = report.serializers.LabelTemplateSerializer filterset_class = LabelFilter filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter] search_fields = ['name', 'description'] ordering_fields = ['name', 'enabled'] -class LabelTemplateDetail(TemplatePermissionMixin, RetrieveUpdateDestroyAPI): +class LabelTemplateDetail( + TemplatePermissionMixin, LabelTemplateMixin, RetrieveUpdateDestroyAPI +): """Detail API endpoint for label template model.""" - queryset = report.models.LabelTemplate.objects.all() - serializer_class = report.serializers.LabelTemplateSerializer - class ReportPrint(GenericAPIView): """API endpoint for printing reports.""" @@ -292,30 +297,40 @@ class ReportPrint(GenericAPIView): item_ids = [item.pk for item in items_to_print] # Offload the task to the background worker - offload_task(report.tasks.print_reports, template.pk, item_ids, output.pk) + offload_task( + report.tasks.print_reports, + template.pk, + item_ids, + output.pk, + user.pk if user else None, + ) output.refresh_from_db() return Response(DataOutputSerializer(output).data, status=201) -class ReportTemplateList(TemplatePermissionMixin, ListCreateAPI): +class ReportTemplateMixin: + """Mixin class for report template API views.""" + + queryset = report.models.ReportTemplate.objects.all().prefetch_related('updated_by') + serializer_class = report.serializers.ReportTemplateSerializer + + +class ReportTemplateList(TemplatePermissionMixin, ReportTemplateMixin, ListCreateAPI): """API endpoint for viewing list of ReportTemplate objects.""" - queryset = report.models.ReportTemplate.objects.all() - serializer_class = report.serializers.ReportTemplateSerializer filterset_class = ReportFilter filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter] search_fields = ['name', 'description'] ordering_fields = ['name', 'enabled'] -class ReportTemplateDetail(TemplatePermissionMixin, RetrieveUpdateDestroyAPI): +class ReportTemplateDetail( + TemplatePermissionMixin, ReportTemplateMixin, RetrieveUpdateDestroyAPI +): """Detail API endpoint for report template model.""" - queryset = report.models.ReportTemplate.objects.all() - serializer_class = report.serializers.ReportTemplateSerializer - class ReportSnippetList(TemplatePermissionMixin, ListCreateAPI): """API endpoint for listing ReportSnippet objects.""" diff --git a/src/backend/InvenTree/report/apps.py b/src/backend/InvenTree/report/apps.py index 534c239546..e72ea19145 100644 --- a/src/backend/InvenTree/report/apps.py +++ b/src/backend/InvenTree/report/apps.py @@ -7,6 +7,7 @@ from django.apps import AppConfig from django.core.exceptions import AppRegistryNotReady, ValidationError from django.core.files.base import ContentFile from django.core.files.storage import default_storage +from django.db import transaction from django.db.utils import IntegrityError, OperationalError, ProgrammingError import structlog @@ -48,6 +49,9 @@ class ReportConfig(AppConfig): if not InvenTree.ready.canAppAccessDatabase(allow_test=False): return # pragma: no cover + if InvenTree.ready.isReadOnlyCommand(): + return # pragma: no cover + with maintenance_mode_on(): try: self.create_default_labels() @@ -160,9 +164,10 @@ class ReportConfig(AppConfig): # Otherwise, create a new entry try: # Create a new entry - report.models.LabelTemplate.objects.create( - **template, template=self.file_from_template('label', filename) - ) + with transaction.atomic(): + report.models.LabelTemplate.objects.create( + **template, template=self.file_from_template('label', filename) + ) logger.info("Creating new label template: '%s'", template['name']) except ValidationError: logger.warning( @@ -224,6 +229,13 @@ class ReportConfig(AppConfig): 'model_type': 'returnorder', 'filename_pattern': 'ReturnOrder-{{ reference }}.pdf', }, + { + 'file': 'inventree_transfer_order_report.html', + 'name': 'InvenTree Transfer Order', + 'description': 'Sample transfer order report', + 'model_type': 'transferorder', + 'filename_pattern': 'TransferOrder-{{ reference }}.pdf', + }, { 'file': 'inventree_test_report.html', 'name': 'InvenTree Test Report', diff --git a/src/backend/InvenTree/report/migrations/0032_labeltemplate_updated_labeltemplate_updated_by_and_more.py b/src/backend/InvenTree/report/migrations/0032_labeltemplate_updated_labeltemplate_updated_by_and_more.py new file mode 100644 index 0000000000..aaf2c9024e --- /dev/null +++ b/src/backend/InvenTree/report/migrations/0032_labeltemplate_updated_labeltemplate_updated_by_and_more.py @@ -0,0 +1,64 @@ +# Generated by Django 5.2.12 on 2026-04-09 01:13 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("report", "0031_reporttemplate_merge"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name="labeltemplate", + name="updated", + field=models.DateTimeField( + blank=True, + default=None, + help_text="Timestamp of last update", + null=True, + verbose_name="Updated", + ), + ), + migrations.AddField( + model_name="labeltemplate", + name="updated_by", + field=models.ForeignKey( + blank=True, + help_text="User who last updated this object", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="%(class)s_updated", + to=settings.AUTH_USER_MODEL, + verbose_name="Update By", + ), + ), + migrations.AddField( + model_name="reporttemplate", + name="updated", + field=models.DateTimeField( + blank=True, + default=None, + help_text="Timestamp of last update", + null=True, + verbose_name="Updated", + ), + ), + migrations.AddField( + model_name="reporttemplate", + name="updated_by", + field=models.ForeignKey( + blank=True, + help_text="User who last updated this object", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="%(class)s_updated", + to=settings.AUTH_USER_MODEL, + verbose_name="Update By", + ), + ), + ] diff --git a/src/backend/InvenTree/report/models.py b/src/backend/InvenTree/report/models.py index 677500ea3b..cae928bdf4 100644 --- a/src/backend/InvenTree/report/models.py +++ b/src/backend/InvenTree/report/models.py @@ -27,7 +27,7 @@ import InvenTree.helpers import InvenTree.models import report.helpers import report.validators -from common.models import DataOutput, RenderChoices +from common.models import DataOutput, RenderChoices, UpdatedUserMixin from common.settings import get_global_setting from InvenTree.helpers_model import get_base_url from InvenTree.models import MetadataMixin @@ -148,7 +148,7 @@ class BaseContextExtension(TypedDict): template_description: Description of the report template template_name: Name of the report template template_revision: Revision of the report template - user: User who made the request to render the template + user: User who is creating the report (if available) """ base_url: str @@ -189,7 +189,9 @@ class ReportContextExtension(TypedDict): merge: bool -class ReportTemplateBase(MetadataMixin, InvenTree.models.InvenTreeModel): +class ReportTemplateBase( + MetadataMixin, UpdatedUserMixin, InvenTree.models.InvenTreeModel +): """Base class for reports, labels.""" class ModelChoices(RenderChoices): @@ -205,8 +207,9 @@ class ReportTemplateBase(MetadataMixin, InvenTree.models.InvenTreeModel): def save(self, *args, **kwargs): """Perform additional actions when the report is saved.""" - # Increment revision number - self.revision += 1 + if kwargs.pop('increment_revision', True): + # Increment revision number + self.revision += 1 super().save() @@ -241,37 +244,39 @@ class ReportTemplateBase(MetadataMixin, InvenTree.models.InvenTreeModel): def generate_filename(self, context, **kwargs) -> str: """Generate a filename for this report.""" template_string = Template(self.filename_pattern) - return template_string.render(Context(context)) - def render_as_string(self, instance, request=None, context=None, **kwargs) -> str: + def render_as_string( + self, instance: models.Model, context: Optional[dict] = None, **kwargs + ) -> str: """Render the report to a HTML string. Arguments: instance: The model instance to render against - request: A HTTPRequest object (optional) context: Django template language contexts (optional) Returns: str: HTML string """ if context is None: - context = self.get_context(instance, request, **kwargs) + context = self.get_context(instance, **kwargs) - return render_to_string(self.template_name, context, request) + return render_to_string(self.template_name, context) - def render(self, instance, request=None, context=None, **kwargs) -> bytes: + def render( + self, instance: models.Model, context: Optional[dict] = None, **kwargs + ) -> bytes: """Render the template to a PDF file. Arguments: instance: The model instance to render against - request: A HTTPRequest object (optional) - context: Django template langaguage contexts (optional) + context: Django template language contexts (optional) + user: The user to associate with the generated report Returns: bytes: PDF data """ - html = self.render_as_string(instance, request, context, **kwargs) + html = self.render_as_string(instance, context=context, **kwargs) pdf = HTML(string=html).write_pdf(pdf_forms=True) return pdf @@ -320,28 +325,28 @@ class ReportTemplateBase(MetadataMixin, InvenTree.models.InvenTreeModel): """Return a filter dict which can be applied to the target model.""" return report.validators.validate_filters(self.filters, model=self.get_model()) - def base_context(self, request=None) -> BaseContextExtension: + def base_context(self, **kwargs) -> BaseContextExtension: """Return base context data (available to all templates).""" return { - 'base_url': get_base_url(request=request), + 'base_url': get_base_url(), 'date': InvenTree.helpers.current_date(), 'datetime': InvenTree.helpers.current_time(), 'template': self, 'template_description': self.description, 'template_name': self.name, 'template_revision': self.revision, - 'user': request.user if request else None, + 'user': kwargs.get('user'), } - def get_context(self, instance, request=None, **kwargs): + def get_context(self, instance: models.Model, **kwargs): """Supply context data to the generic template for rendering. Arguments: instance: The model instance we are printing against - request: The request object (optional) + user: The user to associate with the generated report """ # Provide base context information to all templates - base_context = self.base_context(request=request) + base_context = self.base_context(**kwargs) # Add in an context information provided by the model instance itself context = {**base_context, **instance.report_context()} @@ -420,55 +425,77 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): return report_context - def get_context(self, instance, request=None, **kwargs): - """Supply context data to the report template for rendering.""" - base_context = super().get_context(instance, request) + def get_context(self, instance: models.Model, **kwargs): + """Supply context data to the report template for rendering. + + Arguments: + instance: The model instance we are printing against + """ + base_context = super().get_context(instance, **kwargs) report_context: ReportContextExtension = self.get_report_context() context = {**base_context, **report_context} # Pass the context through to the plugin registry for any additional information - context = self.get_plugin_context(instance, request, context) + context = self.get_plugin_context(instance, context, **kwargs) return context - def get_plugin_context(self, instance, request, context): - """Get the context for the plugin.""" + def get_plugin_context(self, instance: models.Model, context: dict, **kwargs): + """Get the context for the plugin. + + Arguments: + instance: The model instance we are printing against + context: The context dictionary to add to + user: The user to associate with the generated report + """ + user = kwargs.get('user') + for plugin in registry.with_mixin(PluginMixinEnum.REPORT): try: - plugin.add_report_context(self, instance, request, context) + plugin.add_report_context(self, instance, user, context) except Exception: InvenTree.exceptions.log_error('add_report_context', plugin=plugin.slug) return context - def handle_attachment(self, instance, report, report_name, request, debug_mode): + def handle_attachment(self, instance, report, report_name, user, debug_mode): """Attach the generated report to the model instance (if required).""" if self.attach_to_model and not debug_mode: instance.create_attachment( attachment=ContentFile(report, report_name), comment=_(f'Report generated from template {self.name}'), - upload_user=request.user - if request and request.user.is_authenticated - else None, + upload_user=user, ) - def notify_plugins(self, instance, report, request): - """Provide generated report to any interested plugins.""" + def notify_plugins(self, instance, report, user): + """Provide generated report to any interested plugins. + + Arguments: + instance: The model instance we are printing against + report: The generated report object + user: The user to associate with the generated report + """ report_plugins = registry.with_mixin(PluginMixinEnum.REPORT) for plugin in report_plugins: try: - plugin.report_callback(self, instance, report, request) + plugin.report_callback(self, instance, report, user) except Exception: InvenTree.exceptions.log_error('report_callback', plugin=plugin.slug) - def print(self, items: list, request=None, output=None, **kwargs) -> DataOutput: + def print( + self, + items: list, + output: Optional[DataOutput] = None, + user: Optional[AbstractUser] = None, + **kwargs, + ) -> DataOutput: """Print reports for a list of items against this template. Arguments: items: A list of items to print reports for (model instance) - output: The DataOutput object to use (if provided) - request: The request object (optional) + output: The DataOutput object to use + user: The user to associate with the generated report Returns: output: The DataOutput object representing the generated report(s) @@ -486,6 +513,9 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): """ logger.info("Printing %s reports against template '%s'", len(items), self.name) + # Extract user information from the provided context + user = user or getattr(output, 'user', None) + outputs = [] debug_mode = get_global_setting('REPORT_DEBUG_MODE', False) @@ -497,9 +527,7 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): if not output: output = DataOutput.objects.create( total=len(items), - user=request.user - if request and request.user and request.user.is_authenticated - else None, + user=user, progress=0, complete=False, output_type=DataOutput.DataOutputTypes.REPORT, @@ -513,13 +541,13 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): try: if self.merge: - base_context = super().base_context(request) + base_context = super().base_context(user=user) report_context = self.get_report_context() item_contexts = [] for instance in items: instance_context = instance.report_context() instance_context = self.get_plugin_context( - instance, request, instance_context + instance, instance_context, user=user ) item_contexts.append(instance_context) @@ -534,9 +562,11 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): try: if debug_mode: - report = self.render_as_string(instance, request, contexts) + report = self.render_as_string( + instance, user=user, context=contexts + ) else: - report = self.render(instance, request, contexts) + report = self.render(instance, user=user, context=contexts) except TemplateDoesNotExist as e: t_name = str(e) or self.template msg = f'Template file {t_name} does not exist' @@ -555,17 +585,15 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): raise ValidationError(f'{msg}: {e!s}') outputs.append(report) - self.handle_attachment( - instance, report, report_name, request, debug_mode - ) - self.notify_plugins(instance, report, request) + self.handle_attachment(instance, report, report_name, user, debug_mode) + self.notify_plugins(instance, report, user) # Update the progress of the report generation output.progress += 1 output.save() else: for instance in items: - context = self.get_context(instance, request) + context = self.get_context(instance, user=user) if report_name is None: report_name = self.generate_filename(context) @@ -573,9 +601,11 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): # Render the report output try: if debug_mode: - report = self.render_as_string(instance, request, None) + report = self.render_as_string( + instance, user=user, context=context + ) else: - report = self.render(instance, request, None) + report = self.render(instance, user=user, context=None) except TemplateDoesNotExist as e: t_name = str(e) or self.template msg = f'Template file {t_name} does not exist' @@ -596,9 +626,10 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): outputs.append(report) self.handle_attachment( - instance, report, report_name, request, debug_mode + instance, report, report_name, user, debug_mode ) - self.notify_plugins(instance, report, request) + + self.notify_plugins(instance, report, user) # Update the progress of the report generation output.progress += 1 @@ -611,7 +642,6 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): raise ValidationError({ 'error': _('Error generating report'), 'detail': str(exc), - 'path': request.path if request else None, }) if not report_name: @@ -701,10 +731,17 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): }} """ - def get_context(self, instance, request=None, **kwargs): - """Supply context data to the label template for rendering.""" - base_context = super().get_context(instance, request, **kwargs) - label_context: LabelContextExtension = { # type: ignore[invalid-assignment] + def get_context(self, instance: models.Model, *args, **kwargs): + """Supply context data to the label template for rendering. + + Arguments: + instance: The model instance we are printing against + """ + user = kwargs.get('user') + + base_context = super().get_context(instance, **kwargs) + + label_context: LabelContextExtension = { 'width': self.width, 'height': self.height, 'page_style': None, @@ -721,7 +758,7 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): for plugin in plugins: # Let each plugin add its own context data try: - plugin.add_label_context(self, instance, request, context) + plugin.add_label_context(self, instance, user, context) except Exception: InvenTree.exceptions.log_error('add_label_context', plugin=plugin.slug) @@ -731,9 +768,9 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): self, items: list, plugin: InvenTreePlugin, - output=None, - options=None, - request=None, + output: Optional[DataOutput] = None, + options: Optional[dict] = None, + user: Optional[AbstractUser] = None, **kwargs, ) -> DataOutput: """Print labels for a list of items against this template. @@ -741,9 +778,9 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): Arguments: items: A list of items to print labels for (model instance) plugin: The plugin to use for label rendering - output: The DataOutput object to use (if provided) + output: The DataOutput object to use options: Additional options for the label printing plugin (optional) - request: The request object (optional) + user: The user to associate with the generated labels Returns: output: The DataOutput object representing the generated label(s) @@ -755,11 +792,11 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): f"Printing {len(items)} labels against template '{self.name}' using plugin '{plugin.slug}'" ) + user = user or getattr(output, 'user', None) + if not output: output = DataOutput.objects.create( - user=request.user - if request and request.user.is_authenticated - else None, + user=user, total=len(items), progress=0, complete=False, @@ -776,7 +813,9 @@ class LabelTemplate(TemplateUploadMixin, ReportTemplateBase): if hasattr(plugin, 'before_printing'): plugin.before_printing() - plugin.print_labels(self, output, items, request, printing_options=options) + plugin.print_labels( + self, output, items, None, user=user, printing_options=options + ) if hasattr(plugin, 'after_printing'): plugin.after_printing() diff --git a/src/backend/InvenTree/report/serializers.py b/src/backend/InvenTree/report/serializers.py index 5cf2e37e6b..1845724257 100644 --- a/src/backend/InvenTree/report/serializers.py +++ b/src/backend/InvenTree/report/serializers.py @@ -11,6 +11,7 @@ from InvenTree.serializers import ( InvenTreeAttachmentSerializerField, InvenTreeModelSerializer, ) +from users.serializers import UserSerializer class ReportSerializerBase(InvenTreeModelSerializer): @@ -27,6 +28,21 @@ class ReportSerializerBase(InvenTreeModelSerializer): if len(self.fields['model_type'].choices) == 0: self.fields['model_type'].choices = report.helpers.report_model_options() + def save(self, **kwargs): + """Override the save method to capture the user information.""" + user = self.context.get('request').user + + if not user or not user.is_authenticated: + raise PermissionError( + _('User must be authenticated to save report templates') + ) + + instance = super().save(**kwargs) + instance.updated_by = user + instance.save(increment_revision=False) + + return instance + @staticmethod def base_fields(): """Base serializer field set.""" @@ -41,6 +57,9 @@ class ReportSerializerBase(InvenTreeModelSerializer): 'enabled', 'revision', 'attach_to_model', + 'updated', + 'updated_by', + 'updated_by_detail', ] template = InvenTreeAttachmentSerializerField(required=True) @@ -56,6 +75,10 @@ class ReportSerializerBase(InvenTreeModelSerializer): allow_null=False, ) + updated_by_detail = UserSerializer( + source='updated_by', read_only=True, allow_null=True, many=False + ) + class ReportTemplateSerializer(ReportSerializerBase): """Serializer class for report template model.""" diff --git a/src/backend/InvenTree/report/tasks.py b/src/backend/InvenTree/report/tasks.py index 0dae66f274..71106f6ccb 100644 --- a/src/backend/InvenTree/report/tasks.py +++ b/src/backend/InvenTree/report/tasks.py @@ -1,5 +1,7 @@ """Background tasks for the report app.""" +from django.contrib.auth import get_user_model + import structlog from opentelemetry import trace @@ -10,13 +12,16 @@ logger = structlog.get_logger('inventree') @tracer.start_as_current_span('print_reports') -def print_reports(template_id: int, item_ids: list[int], output_id: int, **kwargs): +def print_reports( + template_id: int, item_ids: list[int], output_id: int, user_id: int, **kwargs +): """Print multiple reports against the provided template. Arguments: template_id: The ID of the ReportTemplate to use item_ids: List of item IDs to generate the report against - output_id: The ID of the DataOutput to use (if provided) + output_id: The ID of the DataOutput to use + user_id: The ID of the user to associate with the generated report This function is intended to be called by the background worker, and will continuously update the status of the DataOutput object. @@ -31,6 +36,18 @@ def print_reports(template_id: int, item_ids: list[int], output_id: int, **kwarg log_error('report.tasks.print_reports') return + # Fetch user information + user = None + + if user_id: + try: + user = get_user_model().objects.get(pk=user_id) + except Exception: + log_error('report.tasks.print_reports', user_id=user_id) + + if not user: + user = getattr(output, 'user', None) + # Fetch the items to be included in the report model = template.get_model() items = model.objects.filter(pk__in=item_ids) @@ -38,20 +55,26 @@ def print_reports(template_id: int, item_ids: list[int], output_id: int, **kwarg # Ensure they are sorted by the order of the provided item IDs items = sorted(items, key=lambda item: item_ids.index(item.pk)) - template.print(items, output=output) + template.print(items, output=output, user=user) @tracer.start_as_current_span('print_labels') def print_labels( - template_id: int, item_ids: list[int], output_id: int, plugin_slug: str, **kwargs + template_id: int, + item_ids: list[int], + output_id: int, + user_id: int, + plugin_slug: str, + **kwargs, ): """Print multiple labels against the provided template. Arguments: template_id: The ID of the LabelTemplate to use item_ids: List of item IDs to generate the labels against - output_id: The ID of the DataOutput to use (if provided) - plugin_slug: The ID of the LabelPlugin to use (if provided) + output_id: The ID of the DataOutput to use + user_id: The ID of the user to associate with the generated labels + plugin_slug: The ID of the LabelPlugin to use This function is intended to be called by the background worker, and will continuously update the status of the DataOutput object. @@ -67,6 +90,18 @@ def print_labels( log_error('report.tasks.print_labels') return + # Fetch user information + user = None + + if user_id: + try: + user = get_user_model().objects.get(pk=user_id) + except Exception: + log_error('report.tasks.print_labels', user_id=user_id) + + if not user: + user = getattr(output, 'user', None) + # Fetch the items to be included in the report model = template.get_model() items = model.objects.filter(pk__in=item_ids) @@ -83,4 +118,4 @@ def print_labels( # Extract optional arguments for label printing options = kwargs.pop('options') or {} - template.print(items, plugin, output=output, options=options) + template.print(items, plugin, output=output, user=user, options=options) diff --git a/src/backend/InvenTree/report/templates/report/inventree_transfer_order_report.html b/src/backend/InvenTree/report/templates/report/inventree_transfer_order_report.html new file mode 100644 index 0000000000..1b88d0275f --- /dev/null +++ b/src/backend/InvenTree/report/templates/report/inventree_transfer_order_report.html @@ -0,0 +1,52 @@ +{% extends "report/inventree_order_report_base.html" %} + +{% load i18n %} +{% load report %} +{% load barcode %} +{% load inventree_extras %} +{% load markdownify %} + +{% block header_content %} + +

+ +{% endblock header_content %} + +{% block page_content %} + +

{% trans "Line Items" %}

+ + + + + + + + + + + + + {% for line in lines.all %} + + + + + + + + {% endfor %} + +
{% trans "Part" %}{% trans "Reference" %}{% trans "Quantity" %}{% trans "Transferred" %}{% trans "Note" %}
+
+ {% trans "Part image" %} +
+
+ {{ line.part.full_name }} +
+
{{ line.reference }}{% decimal line.quantity %}{% decimal line.transferred %}{{ line.notes }}
+ +{% endblock page_content %} diff --git a/src/backend/InvenTree/report/templatetags/barcode.py b/src/backend/InvenTree/report/templatetags/barcode.py index 9a87adb3b3..d6641a0abe 100644 --- a/src/backend/InvenTree/report/templatetags/barcode.py +++ b/src/backend/InvenTree/report/templatetags/barcode.py @@ -33,7 +33,7 @@ def image_data(img, fmt='PNG') -> str: def clean_barcode(data): """Return a 'cleaned' string for encoding into a barcode / qrcode. - - This function runs the data through bleach, and removes any malicious HTML content. + - This function sanitizes the data using nh3, and removes any malicious HTML content. - Used to render raw barcode data into the rendered HTML templates """ from InvenTree.helpers import strip_html_tags diff --git a/src/backend/InvenTree/report/templatetags/report.py b/src/backend/InvenTree/report/templatetags/report.py index 5027915206..330aa1980f 100644 --- a/src/backend/InvenTree/report/templatetags/report.py +++ b/src/backend/InvenTree/report/templatetags/report.py @@ -2,15 +2,17 @@ import base64 import logging -import os from datetime import date, datetime from decimal import Decimal, InvalidOperation +from io import BytesIO +from pathlib import Path from typing import Any, Optional from django import template from django.apps.registry import apps -from django.conf import settings -from django.core.exceptions import ValidationError +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.safestring import SafeString, mark_safe @@ -145,32 +147,154 @@ def getkey(container: dict, key: str, backup_value: Optional[Any] = None) -> Any return container.get(key, backup_value) +def media_file_exists(path: Path | str) -> bool: + """Check if a media file exists at the specified path. + + Arguments: + path: The path to the media file, relative to the media storage root + + Returns: + True if the file exists, False otherwise + """ + if not path: + return False + + try: + return default_storage.exists(str(path)) + except SuspiciousFileOperation: + # Prevent path traversal attacks + raise ValidationError(_('Invalid media file path') + f": '{path}'") + + +def static_file_exists(path: Path | str) -> bool: + """Check if a static file exists at the specified path. + + Arguments: + path: The path to the static file, relative to the static storage root + + Returns: + True if the file exists, False otherwise + """ + if not path: + return False + + try: + return staticfiles_storage.exists(str(path)) + except SuspiciousFileOperation: + # Prevent path traversal attacks + raise ValidationError(_('Invalid static file path') + f": '{path}'") + + +def get_static_file_contents( + path: Path | str, raise_error: bool = False +) -> bytes | None: + """Return the contents of a static file. + + Arguments: + path: The path to the static file, relative to the static storage root + raise_error: If True, raise an error if the file cannot be found (default = False) + + Returns: + The contents of the static file, or None if the file cannot be found + """ + if not path: + if raise_error: + raise ValueError('No static file specified') + else: + return None + + if not staticfiles_storage.exists(path): + if raise_error: + raise FileNotFoundError(f'Static file does not exist: {path!s}') + else: + return None + + with staticfiles_storage.open(str(path)) as f: + file_data = f.read() + + return file_data + + +def get_media_file_contents( + path: Path | str, raise_error: bool = False +) -> bytes | None: + """Return the fully qualified file path to an uploaded media file. + + Arguments: + path: The path to the media file, relative to the media storage root + raise_error: If True, raise an error if the file cannot be found (default = False) + + Returns: + The contents of the media file, or None if the file cannot be found + + Raises: + FileNotFoundError: If the requested media file cannot be loaded + PermissionError: If the requested media file is outside of the media root + ValidationError: If the provided path is invalid + + Notes: + - The resulting path is resolved against the media root directory + """ + if not path: + if raise_error: + raise ValueError('No media file specified') + else: + return None + + if not media_file_exists(path): + if raise_error: + raise FileNotFoundError(f'Media file does not exist: {path!s}') + else: + return None + + # Load the file - and return the contents + with default_storage.open(str(path)) as f: + file_data = f.read() + + return file_data + + @register.simple_tag() -def asset(filename): +def asset(filename: str, raise_error: bool = False) -> str | None: """Return fully-qualified path for an upload report asset file. Arguments: filename: Asset filename (relative to the 'assets' media directory) + raise_error: If True, raise an error if the file cannot be found (default = False) Raises: FileNotFoundError: If file does not exist + ValueError: If an invalid filename is provided (e.g. empty string) + ValidationError: If the filename is invalid (e.g. path traversal attempt) """ + if not filename: + if raise_error: + raise ValueError('No asset file specified') + else: + return None + if type(filename) is SafeString: # Prepend an empty string to enforce 'stringiness' filename = '' + filename - # If in debug mode, return URL to the image, not a local file - debug_mode = get_global_setting('REPORT_DEBUG_MODE', cache=False) + # Remove any leading slash characters from the filename, to prevent path traversal attacks + filename = str(filename).lstrip('/\\') - # Test if the file actually exists - full_path = settings.MEDIA_ROOT.joinpath('report', 'assets', filename).resolve() + full_path = Path('report', 'assets', filename) - if not full_path.exists() or not full_path.is_file(): - raise FileNotFoundError(_('Asset file does not exist') + f": '{filename}'") + if not media_file_exists(full_path): + if raise_error: + raise FileNotFoundError(_('Asset file not found') + f": '{filename}'") + else: + return None - if debug_mode: - return os.path.join(settings.MEDIA_URL, 'report', 'assets', filename) - return f'file://{full_path}' + # In debug mode, return a web URL to the asset file (rather than a local file path) + if get_global_setting('REPORT_DEBUG_MODE', cache=False): + return default_storage.url(str(full_path)) + + storage_path = default_storage.path(str(full_path)) + + return f'file://{storage_path}' @register.simple_tag() @@ -182,61 +306,72 @@ def uploaded_image( width: Optional[int] = None, height: Optional[int] = None, rotate: Optional[float] = None, + raise_error: bool = False, **kwargs, ) -> str: """Return raw image data from an 'uploaded' image. Arguments: - filename: The filename of the image relative to the MEDIA_ROOT directory + filename: The filename of the image relative to the media root directory replace_missing: Optionally return a placeholder image if the provided filename does not exist (default = True) replacement_file: The filename of the placeholder image (default = 'blank_image.png') validate: Optionally validate that the file is a valid image file width: Optional width of the image height: Optional height of the image rotate: Optional rotation to apply to the image + raise_error: If True, raise an error if the file cannot be found (default = False) Returns: Binary image data to be rendered directly in a tag Raises: FileNotFoundError: If the file does not exist + ValueError: If an invalid filename is provided (e.g. empty string) """ if type(filename) is SafeString: # Prepend an empty string to enforce 'stringiness' filename = '' + filename + # Strip out any leading slash characters from the filename, to prevent path traversal attacks + filename = str(filename).lstrip('/\\') + # If in debug mode, return URL to the image, not a local file debug_mode = get_global_setting('REPORT_DEBUG_MODE', cache=False) - # Check if the file exists - if not filename: - exists = False - else: - try: - full_path = settings.MEDIA_ROOT.joinpath(filename).resolve() - exists = full_path.exists() and full_path.is_file() - except Exception: # pragma: no cover - exists = False # pragma: no cover - - if exists and validate and not InvenTree.helpers.TestIfImage(full_path): - logger.warning("File '%s' is not a valid image", filename) - exists = False + # Load image data - this will check if the file exists + exists = bool(filename) and media_file_exists(filename) if not exists and not replace_missing: raise FileNotFoundError(_('Image file not found') + f": '{filename}'") + if exists: + img_data = get_media_file_contents(filename, raise_error=raise_error) + + # Check if the image data is valid + if ( + img_data + and validate + and not InvenTree.helpers.TestIfImage(BytesIO(img_data)) + ): + logger.warning("File '%s' is not a valid image", filename) + img_data = None + exists = False + else: + # Load the backup image from the static files directory + replacement_file_path = Path('img', replacement_file) + img_data = get_static_file_contents( + replacement_file_path, raise_error=raise_error + ) + if debug_mode: # In debug mode, return a web path (rather than an encoded image blob) if exists: - return os.path.join(settings.MEDIA_URL, filename) - return os.path.join(settings.STATIC_URL, 'img', replacement_file) + return default_storage.url(filename) - elif not exists: - full_path = settings.STATIC_ROOT.joinpath('img', replacement_file).resolve() + return staticfiles_storage.url(str(Path('img', replacement_file))) - # Load the image, check that it is valid - if full_path.exists() and full_path.is_file(): - img = Image.open(full_path) + if img_data: + img = Image.open(BytesIO(img_data)) else: # A placeholder image showing that the image is missing img = Image.new('RGB', (64, 64), color='red') @@ -288,22 +423,15 @@ def encode_svg_image(filename: str) -> str: # Prepend an empty string to enforce 'stringiness' filename = '' + filename - # Check if the file exists + # Remove any leading slash characters from the filename, to prevent path traversal attacks + filename = str(filename).lstrip('/\\') + if not filename: - exists = False - else: - try: - full_path = settings.MEDIA_ROOT.joinpath(filename).resolve() - exists = full_path.exists() and full_path.is_file() - except Exception: - exists = False + raise FileNotFoundError(_('No image file specified')) - if not exists: - raise FileNotFoundError(_('Image file not found') + f": '{filename}'") - - # Read the file data - with open(full_path, 'rb') as f: - data = f.read() + # 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) # Return the base64-encoded data return 'data:image/svg+xml;charset=utf-8;base64,' + base64.b64encode(data).decode( @@ -323,8 +451,15 @@ def part_image(part: Part, preview: bool = False, thumbnail: bool = False, **kwa Raises: TypeError: If provided part is not a Part instance """ - if type(part) is not Part: + if not part or not isinstance(part, Part): raise TypeError(_('part_image tag requires a Part instance')) + + image_filename = InvenTree.helpers.image2name(part.image, preview, thumbnail) + + if kwargs.get('check_exists'): + if not media_file_exists(image_filename): + raise FileNotFoundError(_('Image file not found') + f": '{image_filename}'") + return uploaded_image( InvenTree.helpers.image2name(part.image, preview, thumbnail), **kwargs ) @@ -338,10 +473,10 @@ def parameter( Arguments: instance: A Model object - parameter_name: The name of the parameter to retrieve + parameter_name: The name of the parameter to retrieve (case insensitive) Returns: - A Parameter object, or None if not found + A Parameter object, or the provided default value if not found """ if instance is None: raise ValueError('parameter tag requires a valid Model instance') @@ -349,12 +484,46 @@ def parameter( if not isinstance(instance, Model) or not hasattr(instance, 'parameters'): raise TypeError("parameter tag requires a Model with 'parameters' attribute") - return ( - instance.parameters + # First try with exact match + if ( + parameter := instance.parameters .prefetch_related('template') .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() + ): + return parameter + + return None + + +@register.simple_tag() +def parameter_value( + instance: Model, parameter_name: str, backup_value: Optional[Any] = None +) -> str: + """Return the value of a Parameter for the given part and parameter name. + + Arguments: + instance: A Model object + parameter_name: The name of the parameter to retrieve (case insensitive) + backup_value: A backup value to return if the parameter is not found + + Returns: + The value of the Parameter, or the backup_value if not found + """ + if param := parameter(instance, parameter_name): + return param.data + + # If the matching parameter is not found, return the backup value + return backup_value @register.simple_tag() @@ -867,3 +1036,196 @@ def include_icon_fonts(ttf: bool = False, woff: bool = False): """ return mark_safe(icon_class + '\n'.join(fonts)) + + +@register.simple_tag() +def lowercase(value: str) -> str: + """Convert a string to lowercase. + + Arguments: + value: The string to be converted + """ + if not value: + return '' + return str(value).lower() + + +@register.simple_tag() +def uppercase(value: str) -> str: + """Convert a string to uppercase. + + Arguments: + value: The string to be converted + """ + if not value: + return '' + return str(value).upper() + + +@register.simple_tag() +def titlecase(value: str) -> str: + """Convert a string to title case. + + Arguments: + value: The string to be converted + """ + if not value: + return '' + return str(value).title() + + +@register.simple_tag() +def strip(value: str, chars: Optional[str] = ' ') -> str: + """Strip leading and trailing characters from a string. + + Arguments: + value: The string to be stripped + chars: The set of characters to strip from the string (default = whitespace) + """ + if not value: + return '' + return str(value).strip(chars) + + +@register.simple_tag() +def lstrip(value: str, chars: Optional[str] = ' ') -> str: + """Strip leading characters from a string. + + Arguments: + value: The string to be stripped + chars: The set of characters to strip from the string (default = whitespace) + """ + if not value: + return '' + return str(value).lstrip(chars) + + +@register.simple_tag() +def rstrip(value: str, chars: Optional[str] = ' ') -> str: + """Strip trailing characters from a string. + + Arguments: + value: The string to be stripped + chars: The set of characters to strip from the string (default = whitespace) + """ + if not value: + return '' + return str(value).rstrip(chars) + + +@register.simple_tag() +def split(value: str, separator: str = ',') -> list: + """Split a string into a list, using the provided separator (default = ','). + + Arguments: + value: The string to be split + separator: The character to use as a separator (default = ',') + """ + if not value: + return [] + return [v.strip() for v in str(value).split(separator)] + + +@register.simple_tag() +def join(value: list, separator: str = ',') -> str: + """Join a list of items into a string, using the provided separator (default = ','). + + Arguments: + value: The list of items to be joined + separator: The character to use as a separator (default = ',') + """ + if not value: + return '' + return separator.join(str(v) for v in value) + + +@register.simple_tag() +def length(value: Any) -> int: + """Return the length of a list or string. + + Arguments: + value: The value to be measured (e.g. a list or string) + """ + if value is None: + return 0 + try: + return len(value) + except TypeError: + return 0 + + +@register.simple_tag() +def replace(value: str, old: str, new: str = '') -> str: + """Replace occurrences of a substring within a string with a new value. + + Arguments: + value: The original string + old: The substring to be replaced + new: The value to replace the old substring with (default = "") + """ + if not value: + return '' + return str(value).replace(old, new) + + +@register.simple_tag() +def first(value: list, default: Any = None) -> Any: + """Return the first item in a list, or a default value if the list is empty. + + Arguments: + value: The list from which to retrieve the first item + default: The value to return if the list is empty (default = None) + """ + if not value: + return default + try: + return value[0] + except (IndexError, TypeError): + return default + + +@register.simple_tag() +def last(value: list, default: Any = None) -> Any: + """Return the last item in a list, or a default value if the list is empty. + + Arguments: + value: The list from which to retrieve the last item + default: The value to return if the list is empty (default = None) + """ + if not value: + return default + try: + return value[-1] + except (IndexError, TypeError): + return default + + +@register.simple_tag() +def reverse(value: list) -> list: + """Return a reversed version of the provided list. + + Arguments: + value: The list to be reversed + """ + if not value: + return [] + try: + return value[::-1] + except TypeError: + return [] + + +@register.simple_tag() +def truncate(value: list, length: int) -> list: + """Return a truncated version of the provided list. + + Arguments: + value: The list to be truncated + length: The maximum length of the returned list + """ + if not value: + return [] + try: + return value[:length] + except TypeError: + return [] diff --git a/src/backend/InvenTree/report/test_tags.py b/src/backend/InvenTree/report/test_tags.py index 337b46e6b2..d8c4df23aa 100644 --- a/src/backend/InvenTree/report/test_tags.py +++ b/src/backend/InvenTree/report/test_tags.py @@ -14,7 +14,6 @@ from djmoney.money import Money from PIL import Image from common.models import InvenTreeSetting, Parameter, ParameterTemplate -from InvenTree.config import get_testfolder_dir from InvenTree.unit_test import InvenTreeTestCase from part.models import Part # TODO fix import: PartParameter, PartParameterTemplate from part.test_api import PartImageTestMixin @@ -62,7 +61,15 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.debug_mode(b) with self.assertRaises(FileNotFoundError): - report_tags.asset('bad_file.txt') + report_tags.asset('bad_file.txt', raise_error=True) + + # Test for missing file, no error + self.assertIsNone(report_tags.asset('missing.txt')) + + self.assertIsNone(report_tags.asset('')) + + with self.assertRaises(ValueError): + report_tags.asset('', raise_error=True) # Create an asset file asset_dir = settings.MEDIA_ROOT.joinpath('report', 'assets') @@ -81,7 +88,28 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.debug_mode(False) asset = report_tags.asset('test.txt') - self.assertEqual(asset, f'file://{asset_dir}/test.txt') + self.assertEqual(asset, f'file://{settings.MEDIA_ROOT}/report/assets/test.txt') + + # Test for attempted path traversal + with self.assertRaises(ValidationError): + report_tags.asset('../../../report/assets/test.txt') + + def test_file_access(self): + """Tests for media and static file access.""" + for fn in [None, '', '@@@@@@', 'fake_file.txt']: + self.assertFalse(report_tags.media_file_exists(fn)) + self.assertFalse(report_tags.static_file_exists(fn)) + + with self.assertRaises(FileNotFoundError): + report_tags.get_media_file_contents('dummy_file.txt', raise_error=True) + + with self.assertRaises(ValueError): + report_tags.get_static_file_contents(None, raise_error=True) + + # Try again, without throwing an error + self.assertIsNone( + report_tags.get_media_file_contents('dummy_file.txt', raise_error=False) + ) def test_uploaded_image(self): """Tests for retrieving uploaded images.""" @@ -148,6 +176,10 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): ) self.assertTrue(img.startswith('data:image/png;charset=utf-8;base64,')) + # Attempted path traversal + with self.assertRaises(ValidationError): + report_tags.uploaded_image('../../../part/images/test.jpg') + def test_part_image(self): """Unit tests for the 'part_image' tag.""" with self.assertRaises(TypeError): @@ -157,8 +189,10 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.create_test_image() obj.refresh_from_db() - report_tags.part_image(obj, preview=True) - report_tags.part_image(obj, thumbnail=True) + r = report_tags.part_image(obj, preview=True) + self.assertIn('data:image/png;charset=utf-8;base64,', r) + r = report_tags.part_image(obj, thumbnail=True) + self.assertIn('data:image/png;charset=utf-8;base64,', r) def test_company_image(self): """Unit tests for the 'company_image' tag.""" @@ -197,6 +231,47 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): logo = report_tags.logo_image() self.assertIn('inventree.png', logo) + def test_string_tags(self): + """Simple tests for the string manipulation tags.""" + self.assertEqual(report_tags.uppercase('hello world'), 'HELLO WORLD') + self.assertEqual(report_tags.lowercase('HELLO WORLD'), 'hello world') + self.assertEqual(report_tags.titlecase('hello world'), 'Hello World') + + self.assertEqual(report_tags.strip(' hello world '), 'hello world') # noqa: B005 + self.assertEqual(report_tags.strip(' hello world ', chars=' hd'), 'ello worl') # noqa: B005 + self.assertEqual(report_tags.strip('xxhelloxx', chars='xy'), 'hello') # noqa: B005 + + self.assertEqual(report_tags.lstrip(' hello world '), 'hello world ') # noqa: B005 + self.assertEqual(report_tags.rstrip(' world ', chars=' dl'), ' wor') # noqa: B005 + + self.assertEqual(report_tags.split('a,b,c', separator=','), ['a', 'b', 'c']) + self.assertEqual(report_tags.split('a,|,b|c', separator='|'), ['a,', ',b', 'c']) + + self.assertEqual(report_tags.join(['a', 'b', 'c'], separator=','), 'a,b,c') + self.assertEqual(report_tags.join(['a', 'b', 'c'], separator='|'), 'a|b|c') + self.assertEqual(report_tags.join(None, separator=','), '') + + self.assertEqual(report_tags.replace('hello world', 'world'), 'hello ') + self.assertEqual( + report_tags.replace('hello world', 'world', 'there'), 'hello there' + ) + + self.assertEqual(report_tags.first('hello world'), 'h') + self.assertEqual(report_tags.last('hello world'), 'd') + self.assertEqual(report_tags.length('hello world'), 11) + self.assertEqual(report_tags.truncate('hello world', length=3), 'hel') + self.assertEqual(report_tags.reverse('hello world'), 'dlrow olleh') + + def test_list_tags(self): + """Simple tests for list manipulation tags.""" + self.assertEqual(report_tags.first([1, 2, 3]), 1) + self.assertEqual(report_tags.last([1, 2, 3]), 3) + self.assertEqual(report_tags.length([1, 2, 3]), 3) + self.assertEqual(report_tags.reverse([1, 2, 3]), [3, 2, 1]) + self.assertEqual(report_tags.truncate([1, 2, 3], 2), [1, 2]) + self.assertEqual(report_tags.join([1, 2, 3], separator=','), '1,2,3') + self.assertEqual(report_tags.join(None, separator=','), '') + def test_maths_tags(self): """Simple tests for mathematical operator tags.""" self.assertEqual(report_tags.add(1, 2), 3) @@ -392,12 +467,16 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): def test_encode_svg_image(self): """Test the encode_svg_image template tag.""" # Generate smallest possible SVG for testing - svg_path = get_testfolder_dir() / 'part_image_123abc.png' + # Store it in the media directory + + img_path = 'part_image_123abc.png' + svg_path = settings.MEDIA_ROOT / img_path + with open(svg_path, 'w', encoding='utf8') as f: f.write(' 0: + self.add_tracking_entry( + StockHistoryCode.EDITED, user, deltas=deltas, notes=notes + ) + + except (ValueError, StockItem.DoesNotExist): + pass + + super().save(*args, **kwargs) + + # If user information is provided, and no existing note exists, create one! + if add_note and self.tracking_info.count() == 0: + tracking_info = {'status': self.status} + + self.add_tracking_entry( + StockHistoryCode.CREATED, + user, + deltas=tracking_info, + notes=notes, + location=self.location, + quantity=float(self.quantity), + ) + + def delete(self, ignore_serial_check: bool = False, **kwargs): + """Custom delete method for StockItem model. + + Arguments: + ignore_serial_check: If True, allow deletion of serialized stock items regardless of global setting + """ + if not ignore_serial_check and not get_global_setting( + 'STOCK_ALLOW_DELETE_SERIALIZED', cache=False + ): + if self.serialized: + raise ValidationError(_('Serialized stock items cannot be deleted')) + + super().delete(**kwargs) + @staticmethod def get_api_url(): """Return API url.""" @@ -521,12 +611,14 @@ class StockItem( status__in=StockStatusGroups.AVAILABLE_CODES, ) - # A query filter which can be used to filter StockItem objects which have expired - EXPIRED_FILTER = ( - IN_STOCK_FILTER - & ~Q(expiry_date=None) - & Q(expiry_date__lt=InvenTree.helpers.current_date()) - ) + @classmethod + def get_expired_filter(cls): + """A query filter which can be used to filter StockItem objects which have expired.""" + return ( + cls.IN_STOCK_FILTER + & ~Q(expiry_date=None) + & Q(expiry_date__lt=InvenTree.helpers.current_date()) + ) @classmethod def _create_serial_numbers(cls, serials: list, **kwargs) -> QuerySet: @@ -632,7 +724,7 @@ class StockItem( items.append(StockItem(**data)) # Create the StockItem objects in bulk - StockItem.objects.bulk_create(items) + 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: @@ -768,82 +860,6 @@ class StockItem( """Return the 'previous' stock item (based on serial number).""" return self.get_next_serialized_item(reverse=True) - def save(self, *args, **kwargs): - """Save this StockItem to the database. - - Performs a number of checks: - - Unique serial number requirement - - Adds a transaction note when the item is first created. - """ - self.validate_unique() - self.clean() - - self.update_serial_number() - - user = kwargs.pop('user', None) - - if user is None: - user = getattr(self, '_user', None) - - # If 'add_note = False' specified, then no tracking note will be added for item creation - add_note = kwargs.pop('add_note', True) - - notes = kwargs.pop('notes', '') - - if self.pk: - # StockItem has already been saved - - # Check if "interesting" fields have been changed - # (we wish to record these as historical records) - - try: - old = StockItem.objects.get(pk=self.pk) - old_custom_status = old.get_custom_status() - custom_status = self.get_custom_status() - - deltas = {} - - # Status changed? - if old.status != self.status: - # Custom status changed? - # Matches custom status tracking behavior of StockChangeStatusSerializer - if old_custom_status != custom_status: - deltas['status'] = custom_status - deltas['status_logical'] = self.status - else: - deltas['status'] = self.status - deltas['status_logical'] = self.status - - if old_custom_status: - deltas['old_status'] = old_custom_status - deltas['old_status_logical'] = old.status - else: - deltas['old_status'] = old.status - deltas['old_status_logical'] = old.status - - if add_note and len(deltas) > 0: - self.add_tracking_entry( - StockHistoryCode.EDITED, user, deltas=deltas, notes=notes - ) - - except (ValueError, StockItem.DoesNotExist): - pass - - super().save(*args, **kwargs) - - # If user information is provided, and no existing note exists, create one! - if add_note and self.tracking_info.count() == 0: - tracking_info = {'status': self.status} - - self.add_tracking_entry( - StockHistoryCode.CREATED, - user, - deltas=tracking_info, - notes=notes, - location=self.location, - quantity=float(self.quantity), - ) - @property def status_label(self): """Return label.""" @@ -920,6 +936,17 @@ 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() + + # 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, '']: + raise ValidationError({ + 'serial': _( + 'Editing of serial numbers is not allowed - this item has already been assigned a serial number' + ) + }) + # Custom validation of batch code self.validate_batch_code() @@ -1509,7 +1536,7 @@ class StockItem( item.save(add_note=False) def is_allocated(self): - """Return True if this StockItem is allocated to a SalesOrder or a Build.""" + """Return True if this StockItem is allocated to a SalesOrder, TransferOrder, or a Build.""" return self.allocation_count() > 0 def build_allocation_count(self, **kwargs): @@ -1569,12 +1596,48 @@ class StockItem( return total + def get_transfer_order_allocations(self, active=True, **kwargs): + """Return a queryset for TransferOrderAllocations against this StockItem, with optional filters. + + Arguments: + active: Filter by 'active' status of the allocation + """ + query = self.transfer_order_allocations.all() + + if filter_allocations := kwargs.get('filter_allocations'): + query = query.filter(**filter_allocations) + + if exclude_allocations := kwargs.get('exclude_allocations'): + query = query.exclude(**exclude_allocations) + + if active is True: + query = query.filter(line__order__status__in=TransferOrderStatusGroups.OPEN) + elif active is False: + query = query.exclude( + line__order__status__in=TransferOrderStatusGroups.OPEN + ) + + return query + + def transfer_order_allocation_count(self, active=True, **kwargs): + """Return the total quantity allocated to TransferOrders.""" + query = self.get_transfer_order_allocations(active=active, **kwargs) + query = query.aggregate(q=Coalesce(Sum('quantity'), Decimal(0))) + + total = query['q'] + + if total is None: + total = Decimal(0) + + return total + def allocation_count(self): """Return the total quantity allocated to builds or orders.""" bo = self.build_allocation_count() so = self.sales_order_allocation_count() + to = self.transfer_order_allocation_count() - return bo + so + return bo + so + to def unallocated_quantity(self): """Return the quantity of this StockItem which is *not* allocated.""" @@ -1971,7 +2034,7 @@ class StockItem( # Copy any test results from this item to the new one item.copyTestResultsFrom(self) - StockItemTracking.objects.bulk_create(history_items) + StockItemTracking.objects.bulk_create(history_items, batch_size=250) # Remove the equivalent number of items self.take_stock( @@ -2006,7 +2069,7 @@ class StockItem( result.stock_item = self results_to_create.append(result) - StockItemTestResult.objects.bulk_create(results_to_create) + StockItemTestResult.objects.bulk_create(results_to_create, batch_size=250) def add_test_result(self, create_template=True, **kwargs): """Helper function to add a new StockItemTestResult. @@ -2304,6 +2367,10 @@ class StockItem( deltas = {'stockitem': self.pk} + transferorder = kwargs.pop('transferorder', None) + if transferorder: + deltas['transferorder'] = transferorder.pk + # Optional fields which can be supplied in a 'move' call for field in StockItem.optional_transfer_fields(): if field in kwargs: @@ -2452,6 +2519,10 @@ class StockItem( ) tracking_info['old_status_logical'] = old_status_logical + transferorder = kwargs.pop('transferorder', None) + if transferorder: + tracking_info['transferorder'] = transferorder.pk + # Optional fields which can be supplied in a 'move' call for field in StockItem.optional_transfer_fields(): if field in kwargs: @@ -2691,6 +2762,10 @@ class StockItem( setattr(self, field, kwargs[field]) deltas[field] = kwargs[field] + transferorder = kwargs.pop('transferorder', None) + if transferorder: + deltas['transferorder'] = transferorder.pk + self.save(add_note=False) self.add_tracking_entry( @@ -3099,4 +3174,6 @@ class StockItemTestResult(InvenTree.models.InvenTreeMetadataModel): help_text=_('The timestamp of the test finish'), ) - date = models.DateTimeField(auto_now_add=True, editable=False) + date = models.DateTimeField( + default=InvenTree.helpers.current_time, verbose_name=_('Date') + ) diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 11ac344e1e..570b4f7e51 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -33,10 +33,10 @@ from generic.states.fields import InvenTreeCustomStatusSerializerMixin from importer.registry import register_importer from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.serializers import ( - FilterableListField, InvenTreeCurrencySerializer, InvenTreeDecimalField, - enable_filter, + OptionalField, + TreePathSerializer, ) from users.serializers import UserSerializer @@ -220,10 +220,20 @@ class StockItemTestResultSerializer( 'template', 'template_detail', ] - read_only_fields = ['pk', 'user', 'date'] + read_only_fields = ['pk'] - user_detail = enable_filter( - UserSerializer(source='user', read_only=True, allow_null=True), + def __init__(self, *args, **kwargs): + """Handle custom initialization for the serializer.""" + super().__init__(*args, **kwargs) + + if not self._is_importing: + # Unless we are importing data, mark the 'user' and 'date' fields as read-only + self.fields['user'].read_only = True + self.fields['date'].read_only = True + + user_detail = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={'source': 'user', 'read_only': True, 'allow_null': True}, prefetch_fields=['user'], ) @@ -236,10 +246,9 @@ class StockItemTestResultSerializer( label=_('Test template for this result'), ) - template_detail = enable_filter( - part_serializers.PartTestTemplateSerializer( - source='template', read_only=True, allow_null=True - ), + template_detail = OptionalField( + serializer_class=part_serializers.PartTestTemplateSerializer, + serializer_kwargs={'source': 'template', 'read_only': True, 'allow_null': True}, prefetch_fields=['template'], ) @@ -368,20 +377,20 @@ class StockItemSerializer( 'purchase_price_currency', 'use_pack_size', 'serial_numbers', - 'tests', # Annotated fields 'allocated', 'expired', 'installed_items', 'child_items', - 'location_path', 'stale', - 'tracking_items', - 'tags', - # Detail fields (FK relationships) - 'supplier_part_detail', - 'part_detail', + # Optional fields (FK relationships) 'location_detail', + 'location_path', + 'part_detail', + 'supplier_part_detail', + 'tags', + 'tests', + 'tracking_items', ] read_only_fields = [ 'allocated', @@ -413,17 +422,22 @@ class StockItemSerializer( parent = serializers.PrimaryKeyRelatedField( many=False, read_only=True, + required=False, + allow_null=True, label=_('Parent Item'), help_text=_('Parent stock item'), ) - location_path = enable_filter( - FilterableListField( - child=serializers.DictField(), - source='location.get_path', - read_only=True, - allow_null=True, - ), + location_path = OptionalField( + serializer_class=TreePathSerializer, + serializer_kwargs={ + 'source': 'location.get_path', + 'extra_fields': ['icon'], + 'many': True, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='path_detail', ) @@ -506,6 +520,8 @@ class StockItemSerializer( allocated=Coalesce( SubquerySum('sales_order_allocations__quantity'), Decimal(0) ) + # For now, stock allocated to a transfer order will not impact its availability + # + Coalesce(SubquerySum('transfer_order_allocations__quantity'), Decimal(0)) + Coalesce(SubquerySum('allocations__quantity'), Decimal(0)) ) @@ -516,7 +532,7 @@ class StockItemSerializer( queryset = queryset.annotate( expired=Case( When( - StockItem.EXPIRED_FILTER, + StockItem.get_expired_filter(), then=Value(True, output_field=BooleanField()), ), default=Value(False, output_field=BooleanField()), @@ -566,19 +582,20 @@ class StockItemSerializer( ) # Optional detail fields, which can be appended via query parameters - supplier_part_detail = enable_filter( - company_serializers.SupplierPartSerializer( - label=_('Supplier Part'), - source='supplier_part', - brief=True, - supplier_detail=False, - manufacturer_detail=False, - part_detail=False, - many=False, - read_only=True, - allow_null=True, - ), - False, + supplier_part_detail = OptionalField( + serializer_class=company_serializers.SupplierPartSerializer, + serializer_kwargs={ + 'label': _('Supplier Part'), + 'source': 'supplier_part', + 'brief': True, + 'supplier_detail': False, + 'manufacturer_detail': False, + 'part_detail': False, + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=[ 'supplier_part__supplier', 'supplier_part__purchase_order_line_items', @@ -586,30 +603,40 @@ class StockItemSerializer( ], ) - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - label=_('Part'), source='part', many=False, read_only=True, allow_null=True - ), - True, + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'label': _('Part'), + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=True, ) - location_detail = enable_filter( - LocationBriefSerializer( - label=_('Location'), - source='location', - many=False, - read_only=True, - allow_null=True, - ), - False, + location_detail = OptionalField( + serializer_class=LocationBriefSerializer, + serializer_kwargs={ + 'label': _('Location'), + 'source': 'location', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=['location'], ) - tests = enable_filter( - StockItemTestResultSerializer( - source='test_results', many=True, read_only=True, allow_null=True - ), - False, + tests = OptionalField( + serializer_class=StockItemTestResultSerializer, + serializer_kwargs={ + 'source': 'test_results', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, + default_include=False, prefetch_fields=[ 'test_results', 'test_results__user', @@ -1103,7 +1130,7 @@ class StockChangeStatusSerializer(serializers.Serializer): ) # Create tracking entries - StockItemTracking.objects.bulk_create(transaction_notes) + StockItemTracking.objects.bulk_create(transaction_notes, batch_size=250) class StockLocationTypeSerializer(InvenTree.serializers.InvenTreeModelSerializer): @@ -1142,6 +1169,27 @@ class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer): return queryset.annotate(sublocations=stock.filters.annotate_sub_locations()) +class LocationDeleteSerializer(serializers.Serializer): + """Serializer for deleting a stock location.""" + + class Meta: + """Metaclass options.""" + + fields = ['delete_stock_items', 'delete_sub_locations'] + + delete_stock_items = serializers.BooleanField( + required=True, + label=_('Delete Stock Items'), + help_text=_('Delete all stock items contained within this location'), + ) + + delete_sub_locations = serializers.BooleanField( + required=True, + label=_('Delete Sublocations'), + help_text=_('Delete all sub-locations contained within this location'), + ) + + @register_importer() class LocationSerializer( InvenTree.serializers.FilterableSerializerMixin, @@ -1211,13 +1259,16 @@ class LocationSerializer( tags = common.filters.enable_tags_filter() - path = enable_filter( - FilterableListField( - child=serializers.DictField(), - source='get_path', - read_only=True, - allow_null=True, - ), + path = OptionalField( + serializer_class=TreePathSerializer, + serializer_kwargs={ + 'many': True, + 'source': 'get_path', + 'extra_fields': ['icon'], + 'read_only': True, + 'allow_null': True, + }, + default_include=False, filter_name='path_detail', ) @@ -1262,21 +1313,37 @@ class StockTrackingSerializer( label = serializers.CharField(read_only=True) - item_detail = enable_filter( - StockItemSerializer(source='item', many=False, read_only=True, allow_null=True), + item_detail = OptionalField( + serializer_class=StockItemSerializer, + serializer_kwargs={ + 'source': 'item', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['item', 'item__part'], ) - part_detail = enable_filter( - part_serializers.PartBriefSerializer( - source='part', many=False, read_only=True, allow_null=True - ), + part_detail = OptionalField( + serializer_class=part_serializers.PartBriefSerializer, + serializer_kwargs={ + 'source': 'part', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, default_include=False, prefetch_fields=['part'], ) - user_detail = enable_filter( - UserSerializer(source='user', many=False, read_only=True, allow_null=True), + user_detail = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={ + 'source': 'user', + 'many': False, + 'read_only': True, + 'allow_null': True, + }, prefetch_fields=['user'], ) @@ -1325,6 +1392,10 @@ class StockAssignmentItemSerializer(serializers.Serializer): if item.sales_order_allocations.count() > 0: raise ValidationError(_('Item is allocated to a sales order')) + # The item must not be allocated to a transfer order + if item.transfer_order_allocations.count() > 0: + raise ValidationError(_('Item is allocated to a transfer order')) + # The item must not be allocated to a build order if item.allocations.count() > 0: raise ValidationError(_('Item is allocated to a build order')) diff --git a/src/backend/InvenTree/stock/test_api.py b/src/backend/InvenTree/stock/test_api.py index f23524eddf..38903f968a 100644 --- a/src/backend/InvenTree/stock/test_api.py +++ b/src/backend/InvenTree/stock/test_api.py @@ -3,7 +3,6 @@ import os import random from datetime import datetime, timedelta -from enum import IntEnum from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -142,13 +141,6 @@ class StockLocationTest(StockAPITestCase): def test_stock_location_delete(self): """Test stock location deletion with different parameters.""" - - class Target(IntEnum): - move_sub_locations_to_parent_move_stockitems_to_parent = (0,) - move_sub_locations_to_parent_delete_stockitems = (1,) - delete_sub_locations_move_stockitems_to_parent = (2,) - delete_sub_locations_delete_stockitems = (3,) - # First, construct a set of template / variant parts part = Part.objects.create( name='Part for stock item creation', @@ -157,117 +149,95 @@ class StockLocationTest(StockAPITestCase): is_template=False, ) - for i in range(4): - delete_sub_locations: bool = False - delete_stock_items: bool = False - - if i in ( - Target.move_sub_locations_to_parent_delete_stockitems, - Target.delete_sub_locations_delete_stockitems, - ): - delete_stock_items = True - if i in ( - Target.delete_sub_locations_move_stockitems_to_parent, - Target.delete_sub_locations_delete_stockitems, - ): - delete_sub_locations = True - - # Create a parent stock location - parent_stock_location = StockLocation.objects.create( - name='Parent stock location', - description='This is the parent stock location where the sub categories and stock items are moved to', - parent=None, - ) - - stocklocation_count_before = StockLocation.objects.count() - stock_location_count_before = StockItem.objects.count() - - # Create a stock location to be deleted - stock_location_to_delete = StockLocation.objects.create( - name='Stock location to delete', - description='This is the stock location to be deleted', - parent=parent_stock_location, - ) - - url = reverse( - 'api-location-detail', kwargs={'pk': stock_location_to_delete.id} - ) - - stock_items = [] - # Create stock items in the location to be deleted - for jj in range(3): - stock_items.append( - StockItem.objects.create( - batch=f'Batch xyz {jj}', - location=stock_location_to_delete, - part=part, - ) + for delete_sub_locations in [False, True]: + for delete_stock_items in [False, True]: + # Create a parent stock location + parent_stock_location = StockLocation.objects.create( + name='Parent stock location', + description='This is the parent stock location where the sub categories and stock items are moved to', + parent=None, ) - child_stock_locations = [] - child_stock_locations_items = [] - # Create sub location under the stock location to be deleted - for ii in range(3): - child = StockLocation.objects.create( - name=f'Sub-location {ii}', - description='A sub-location of the deleted stock location', - parent=stock_location_to_delete, - ) - child_stock_locations.append(child) + location_count_before = StockLocation.objects.count() + item_count_before = StockItem.objects.count() - # Create stock items in the sub locations + # Create a stock location to be deleted + location_to_delete = StockLocation.objects.create( + name='Stock location to delete', + description='This is the stock location to be deleted', + parent=parent_stock_location, + ) + + url = reverse( + 'api-location-detail', kwargs={'pk': location_to_delete.id} + ) + + stock_items = [] + + # Create stock items in the location to be deleted for jj in range(3): - child_stock_locations_items.append( + stock_items.append( StockItem.objects.create( - batch=f'B xyz {jj}', part=part, location=child + batch=f'Batch xyz {jj}', + location=location_to_delete, + part=part, ) ) - # Delete the created stock location - params = {} - if delete_stock_items: - params['delete_stock_items'] = '1' - if delete_sub_locations: - params['delete_sub_locations'] = '1' - response = self.delete(url, params, expected_code=204) + child_locations = [] + child_locations_items = [] - self.assertEqual(response.status_code, 204) + # Create sub location under the stock location to be deleted + for ii in range(3): + child = StockLocation.objects.create( + name=f'Sub-location {ii}', + description='A sub-location of the deleted stock location', + parent=location_to_delete, + ) + child_locations.append(child) - if delete_stock_items: - if i == Target.delete_sub_locations_delete_stockitems: - # Check if all sub-categories deleted + # Create stock items in the sub locations + for jj in range(3): + child_locations_items.append( + StockItem.objects.create( + batch=f'B xyz {jj}', part=part, location=child + ) + ) + + # Delete the created stock location + params = { + 'delete_stock_items': delete_stock_items, + 'delete_sub_locations': delete_sub_locations, + } + + response = self.delete(url, data=params, expected_code=204) + + self.assertEqual(response.status_code, 204) + + # If we were deleting stock items, the count must not have changed + if delete_stock_items: + extra_items = 0 if delete_sub_locations else 9 self.assertEqual( - StockItem.objects.count(), stock_location_count_before + StockItem.objects.count(), item_count_before + extra_items ) - elif i == Target.move_sub_locations_to_parent_delete_stockitems: - # Check if all stock locations deleted - self.assertEqual( - StockItem.objects.count(), - stock_location_count_before + len(child_stock_locations_items), - ) - else: - # Stock locations moved to the parent location - for stock_item in stock_items: - stock_item.refresh_from_db() - self.assertEqual(stock_item.location, parent_stock_location) + else: + # Stock items moved to the parent location + self.assertGreater(StockItem.objects.count(), item_count_before) + + for stock_item in stock_items: + stock_item.refresh_from_db() + self.assertEqual(stock_item.location, parent_stock_location) if delete_sub_locations: - for child_stock_location_item in child_stock_locations_items: - child_stock_location_item.refresh_from_db() - self.assertEqual( - child_stock_location_item.location, parent_stock_location - ) - - if delete_sub_locations: - # Check if all sub-locations are deleted - self.assertEqual( - StockLocation.objects.count(), stocklocation_count_before - ) - else: - # Check if all sub-locations moved to the parent - for child in child_stock_locations: - child.refresh_from_db() - self.assertEqual(child.parent, parent_stock_location) + # Check if all sub-categories deleted + self.assertEqual( + StockLocation.objects.count(), location_count_before + ) + else: + # Check if all sub-categories moved to the parent category + for location in child_locations: + location.refresh_from_db() + self.assertEqual(location.parent, parent_stock_location) def test_output_options(self): """Test output options.""" @@ -575,6 +545,79 @@ class StockItemListTest(StockAPITestCase): for ordering in ['part', 'location', 'stock', 'status', 'IPN', 'MPN', 'SKU']: self.run_ordering_test(self.list_url, ordering) + def test_pagination(self): + """Test that pagination boundaries are observed correctly. + + Ref: https://github.com/inventree/InvenTree/issues/11442 + """ + location = StockLocation.objects.first() + part = Part.objects.first() + + items = [] + + # Delete all existing stock item objects + for item in StockItem.objects.all(): + 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, + ) + ) + + StockItem.objects.bulk_create(items, batch_size=250) + + self.assertEqual(StockItem.objects.count(), 1000) + + url = reverse('api-stock-list') + + # Keep track of the unique PKs we have seen in the results + unique_pks = set() + + for idx in range(0, 100, 10): + data = self.get(url, {'limit': 10, 'offset': idx}).data + self.assertEqual(data['count'], 1000) + self.assertEqual(len(data['results']), 10) + + for item in data['results']: + self.assertNotIn( + item['pk'], + unique_pks, + f'Duplicate PK {item["pk"]} found in paginated results @ page {idx // 10}', + ) + unique_pks.add(item['pk']) + + self.assertEqual( + len(unique_pks), 100, 'Expected to see 100 unique PKs in paginated results' + ) + + # Run same test again, with reverse ordering on part IPN + unique_pks = set() + + for idx in range(0, 100, 10): + data = self.get(url, {'limit': 10, 'offset': idx, 'ordering': '-IPN'}).data + self.assertEqual(data['count'], 1000) + self.assertEqual(len(data['results']), 10) + + for item in data['results']: + self.assertNotIn( + item['pk'], + unique_pks, + f'Duplicate PK {item["pk"]} found in paginated results @ page {idx // 10} with reverse ordering', + ) + unique_pks.add(item['pk']) + + self.assertEqual( + len(unique_pks), 100, 'Expected to see 100 unique PKs in paginated results' + ) + def test_top_level_filtering(self): """Test filtering against "top level" stock location.""" # No filters, should return *all* items @@ -963,7 +1006,7 @@ class StockItemListTest(StockAPITestCase): # Note: While the export is quick on pgsql, it is still quite slow on sqlite3 with self.export_data( self.list_url, - max_query_count=50, + max_query_count=100, max_query_time=12.0, # Test time increased due to worker variability ) as data_file: data = self.process_csv(data_file) @@ -1342,12 +1385,19 @@ class StockItemTest(StockAPITestCase): """Test the default location functionality, if a 'location' is not specified in the creation request.""" # The part 'R_4K7_0603' (pk=4) has a default location specified + # Create a new StockItem instance response = self.post( self.list_url, data={'part': 4, 'quantity': 10}, expected_code=201 ) self.assertEqual(response.data[0]['location'], 2) + # Check that the item was associated with the correct user + item = StockItem.objects.get(pk=response.data[0]['pk']) + self.assertEqual(item.tracking_info_count, 1) + tracking = item.tracking_info.first() + self.assertEqual(tracking.user, self.user) + # What if we explicitly set the location to a different value? response = self.post( @@ -1564,6 +1614,36 @@ class StockItemTest(StockAPITestCase): ) self.assertEqual(trackable_part.get_stock_count(), 10) + def test_edit_serial(self): + """Test that we can edit serial numbers via the API.""" + item = StockItem.objects.create( + part=Part.objects.filter(trackable=True).first(), + quantity=1, + location=StockLocation.objects.first(), + ) + + set_global_setting('STOCK_ALLOW_EDIT_SERIAL', False) + + url = reverse('api-stock-detail', kwargs={'pk': item.pk}) + + # Edit the serial number + # This should succeed, as the initial serial number is blank + response = self.patch(url, {'serial': '54321'}, expected_code=200) + self.assertEqual(response.data['serial'], '54321') + + # Edit it again - this time, should fail as the serial number is already set + response = self.patch(url, {'serial': '98765'}, expected_code=400) + self.assertIn('Editing of serial numbers is not allowed', str(response.data)) + + # Ensure that changing a different field does not cause an error + response = self.patch(url, {'batch': 'abcde'}, expected_code=200) + self.assertEqual(response.data['batch'], 'abcde') + + # Adjust the setting to allow serial editing + set_global_setting('STOCK_ALLOW_EDIT_SERIAL', True) + response = self.patch(url, {'serial': '98765'}, expected_code=200) + self.assertEqual(response.data['serial'], '98765') + def test_default_expiry(self): """Test that the "default_expiry" functionality works via the API. @@ -1931,6 +2011,33 @@ class StockItemTest(StockAPITestCase): self.assertEqual(tracking.deltas['status'], StockStatus.OK.value) self.assertEqual(tracking.deltas['status_logical'], StockStatus.OK.value) + def test_bulk_batch_change(self): + """Test that we can bulk-change batch code for a set of stock items.""" + url = reverse('api-stock-list') + + # Find the first 10 stock items + items = StockItem.objects.all()[:10] + self.assertEqual(len(items), 10) + + response = self.patch( + url, + data={'items': [item.pk for item in items], 'batch': 'NEW-BATCH-CODE'}, + max_query_count=300, + ) + + data = response.data + + self.assertEqual(data['success'], 'Updated 10 items') + self.assertEqual(len(data['items']), 10) + + for item in data['items']: + self.assertEqual(item['batch'], 'NEW-BATCH-CODE') + + # Check database items also + for item in items: + item.refresh_from_db() + self.assertEqual(item.batch, 'NEW-BATCH-CODE') + class StocktakeTest(StockAPITestCase): """Series of tests for the Stocktake API.""" @@ -2074,6 +2181,37 @@ class StockItemDeletionTest(StockAPITestCase): self.assertEqual(StockItem.objects.count(), n) + def test_delete_serialized(self): + """Test deletion of serialized stock items.""" + trackable_part = part.models.Part.objects.create( + name='My part', + description='A trackable part', + trackable=True, + default_location=StockLocation.objects.get(pk=1), + ) + + stock_item = StockItem.objects.create( + part=trackable_part, quantity=1, serial='12345' + ) + + set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', False) + + response = self.delete( + reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=400 + ) + + self.assertIn('Serialized stock items cannot be deleted', str(response.data)) + + set_global_setting('STOCK_ALLOW_DELETE_SERIALIZED', True) + + response = self.delete( + reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=204 + ) + + self.get( + reverse('api-stock-detail', kwargs={'pk': stock_item.pk}), expected_code=404 + ) + class StockTestResultTest(StockAPITestCase): """Tests for StockTestResult APIs.""" @@ -2325,17 +2463,7 @@ class StockTestResultTest(StockAPITestCase): self.delete(url, {}, expected_code=400) # Now, let's delete all the newly created items with a single API request - # However, we will provide incorrect filters - response = self.delete( - url, {'items': tests, 'filters': {'stock_item': 10}}, expected_code=400 - ) - - self.assertEqual(StockItemTestResult.objects.count(), n + 50) - - # Try again, but with the correct filters this time - response = self.delete( - url, {'items': tests, 'filters': {'stock_item': 1}}, expected_code=200 - ) + response = self.delete(url, {'items': tests}, expected_code=200) self.assertEqual(StockItemTestResult.objects.count(), n) diff --git a/src/backend/InvenTree/users/api.py b/src/backend/InvenTree/users/api.py index 42201ed095..13ef2fa501 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 ( @@ -256,7 +257,7 @@ class UserList(ListCreateAPI): - Otherwise authenticated users have read-only access """ - queryset = User.objects.all() + queryset = User.objects.all().prefetch_related('groups') serializer_class = UserCreateSerializer # User must have the right role, AND be a staff user, else read-only @@ -367,49 +368,44 @@ class GetAuthToken(GenericAPIView): - Existing tokens are *never* exposed again via the API - Once the token is provided, it can be used for auth until it expires """ - if request.user.is_authenticated: - user = request.user - name = request.query_params.get('name', '') + if not request.user.is_authenticated: + raise exceptions.NotAuthenticated() # pragma: no cover - name = ApiToken.sanitize_name(name) + user = request.user + name = request.query_params.get('name', '') - today = datetime.date.today() + name = ApiToken.sanitize_name(name) - # Find existing token, which has not expired - token = ApiToken.objects.filter( - user=user, name=name, revoked=False, expiry__gte=today - ).first() + today = datetime.date.today() - if not token: - # User is authenticated, and requesting a token against the provided name. - token = ApiToken.objects.create(user=request.user, name=name) + # Find existing token, which has not expired + token = ApiToken.objects.filter( + user=user, name=name, revoked=False, expiry__gte=today + ).first() - logger.info( - "Created new API token for user '%s' (name='%s')", - user.username, - name, - ) + if not token: + # User is authenticated, and requesting a token against the provided name. + token = ApiToken.objects.create(user=request.user, name=name) + + logger.info( + "Created new API token for user '%s' (name='%s')", user.username, name + ) # Add some metadata about the request - token.set_metadata('user_agent', request.headers.get('user-agent', '')) - token.set_metadata('remote_addr', request.META.get('REMOTE_ADDR', '')) - token.set_metadata('remote_host', request.META.get('REMOTE_HOST', '')) - token.set_metadata('remote_user', request.META.get('REMOTE_USER', '')) - token.set_metadata('server_name', request.META.get('SERVER_NAME', '')) - token.set_metadata('server_port', request.META.get('SERVER_PORT', '')) + token.set_metadata('user_agent', request.headers.get('user-agent', '')) + token.set_metadata('remote_addr', request.META.get('REMOTE_ADDR', '')) + token.set_metadata('remote_host', request.META.get('REMOTE_HOST', '')) + token.set_metadata('remote_user', request.META.get('REMOTE_USER', '')) + token.set_metadata('server_name', request.META.get('SERVER_NAME', '')) + token.set_metadata('server_port', request.META.get('SERVER_PORT', '')) - data = {'token': token.key, 'name': token.name, 'expiry': token.expiry} + data = {'token': token.key, 'name': token.name, 'expiry': token.expiry} - # Ensure that the users session is logged in - if not get_user(request).is_authenticated: - login( - request, user, backend='django.contrib.auth.backends.ModelBackend' - ) + # Ensure that the users session is logged in + if not get_user(request).is_authenticated: + login(request, user, backend='django.contrib.auth.backends.ModelBackend') - return Response(data) - - else: - raise exceptions.NotAuthenticated() # pragma: no cover + return Response(data) class TokenMixin: @@ -506,8 +502,38 @@ class UserProfileDetail(RetrieveUpdateAPI): user_urls = [ - path('roles/', RoleDetails.as_view(), name='api-user-roles'), - path('token/', ensure_csrf_cookie(GetAuthToken.as_view()), name='api-token'), + # 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/', + include([ + path('profile/', UserProfileDetail.as_view(), name='api-user-profile'), + path('roles/', RoleDetails.as_view(), name='api-user-roles'), + path( + 'token/', ensure_csrf_cookie(GetAuthToken.as_view()), name='api-token' + ), + path('', MeUserDetail.as_view(), name='api-user-me'), + ]), + ), + # User related endpoints path( 'tokens/', include([ @@ -515,8 +541,6 @@ user_urls = [ path('', TokenListView.as_view(), name='api-token-list'), ]), ), - path('me/', MeUserDetail.as_view(), name='api-user-me'), - path('profile/', UserProfileDetail.as_view(), name='api-user-profile'), path( 'owner/', include([ diff --git a/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py b/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py index 6dd75904a9..428edaecfd 100644 --- a/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py +++ b/src/backend/InvenTree/users/migrations/0011_auto_20240523_1640.py @@ -1,11 +1,16 @@ # Generated by Django 4.2.12 on 2024-05-23 16:40 +import structlog + from importlib import import_module from django.conf import settings from django.db import migrations +logger = structlog.getLogger('inventree') + + def clear_sessions(apps, schema_editor): # pragma: no cover """Clear all user sessions.""" @@ -16,7 +21,7 @@ def clear_sessions(apps, schema_editor): # pragma: no cover try: engine = import_module(settings.SESSION_ENGINE) engine.SessionStore.clear_expired() - print('\nCleared all user sessions to deal with GHSA-2crp-q9pc-457j') + logger.info('Cleared all user sessions to deal with GHSA-2crp-q9pc-457j') except Exception: # Database may not be ready yet, so this does not matter anyhow pass diff --git a/src/backend/InvenTree/users/models.py b/src/backend/InvenTree/users/models.py index 3ead74515d..54fb8ae2da 100644 --- a/src/backend/InvenTree/users/models.py +++ b/src/backend/InvenTree/users/models.py @@ -24,7 +24,7 @@ from rest_framework.authtoken.models import Token as AuthToken import InvenTree.helpers import InvenTree.models from common.settings import get_global_setting -from InvenTree.ready import isImportingData +from InvenTree.ready import isImportingData, isReadOnlyCommand from .ruleset import RULESET_CHOICES, get_ruleset_models @@ -179,9 +179,7 @@ class ApiToken(AuthToken, InvenTree.models.MetadataMixin): if self.pk is None: return self.key # pragma: no cover - M = len(self.key) - 20 - - return self.key[:8] + '*' * M + self.key[-12:] + return InvenTree.helpers.sanitize_token(self.key) @property @admin.display(boolean=True, description=_('Expired')) @@ -463,7 +461,7 @@ class Owner(models.Model): def create_owner(sender, instance, **kwargs): """Callback function to create a new owner instance after either a new group or user instance is saved.""" # Ignore during data import process to avoid data duplication - if not isImportingData(): + if not isReadOnlyCommand() and not isImportingData(): Owner.create(obj=instance) @@ -600,6 +598,10 @@ class UserProfile(InvenTree.models.MetadataMixin): @receiver(post_save, sender=User) def create_or_update_user_profile(sender, instance, created, **kwargs): """Create or update user profile when user is saved.""" + # Disable profile creation if importing data from file or running a read-only command + if isReadOnlyCommand() or isImportingData(): + return + if created: UserProfile.objects.create(user=instance) instance.profile.save() @@ -629,6 +631,10 @@ def validate_primary_group_on_delete(sender, instance, **kwargs): @receiver(m2m_changed, sender=User.groups.through) def validate_primary_group_on_group_change(sender, instance, action, **kwargs): """Validate primary_group on user profiles when a group is added or removed.""" + # Disable user profile validation if importing data from file + if isImportingData(): + return + if action in ['post_add', 'post_remove']: profile = instance.profile if profile.primary_group and profile.primary_group not in instance.groups.all(): diff --git a/src/backend/InvenTree/users/oauth2_scopes.py b/src/backend/InvenTree/users/oauth2_scopes.py index b5e687ce1f..52656a33fa 100644 --- a/src/backend/InvenTree/users/oauth2_scopes.py +++ b/src/backend/InvenTree/users/oauth2_scopes.py @@ -15,10 +15,12 @@ _roles = { 'part': 'Role Parts', 'stock_location': 'Role Stock Locations', 'stock': 'Role Stock Items', + 'bom': 'Role Bills of Material', 'build': 'Role Build Orders', 'purchase_order': 'Role Purchase Orders', 'sales_order': 'Role Sales Orders', 'return_order': 'Role Return Orders', + 'transfer_order': 'Role Transfer Orders', } _methods = {'view': 'GET', 'add': 'POST', 'change': 'PUT / PATCH', 'delete': 'DELETE'} diff --git a/src/backend/InvenTree/users/permissions.py b/src/backend/InvenTree/users/permissions.py index 7c93f5ec97..c3d7c964b1 100644 --- a/src/backend/InvenTree/users/permissions.py +++ b/src/backend/InvenTree/users/permissions.py @@ -195,6 +195,11 @@ def check_user_permission( result = user.has_perm(permission_name) + # If the user does not have permissions (as determined above), check if the model class provides a custom permission check method + # This is required for non-standard models (i.e. defined via plugins), which do not have the required ruleset definitions + if not result and hasattr(model, 'check_user_permission'): # pragma: no cover + result = model.check_user_permission(user, permission) + # Save result to session-cache InvenTree.cache.set_session_cache(cache_key, result) diff --git a/src/backend/InvenTree/users/ruleset.py b/src/backend/InvenTree/users/ruleset.py index ed70b79b4d..3787eb89b9 100644 --- a/src/backend/InvenTree/users/ruleset.py +++ b/src/backend/InvenTree/users/ruleset.py @@ -12,12 +12,14 @@ class RuleSetEnum(StringEnum): ADMIN = 'admin' PART_CATEGORY = 'part_category' PART = 'part' + BOM = 'bom' STOCK_LOCATION = 'stock_location' STOCK = 'stock' BUILD = 'build' PURCHASE_ORDER = 'purchase_order' SALES_ORDER = 'sales_order' RETURN_ORDER = 'return_order' + TRANSFER_ORDER = 'transfer_order' # This is a list of all the ruleset choices available in the system. @@ -26,12 +28,14 @@ RULESET_CHOICES = [ (RuleSetEnum.ADMIN, _('Admin')), (RuleSetEnum.PART_CATEGORY, _('Part Categories')), (RuleSetEnum.PART, _('Parts')), + (RuleSetEnum.BOM, _('Bills of Material')), (RuleSetEnum.STOCK_LOCATION, _('Stock Locations')), (RuleSetEnum.STOCK, _('Stock Items')), (RuleSetEnum.BUILD, _('Build Orders')), (RuleSetEnum.PURCHASE_ORDER, _('Purchase Orders')), (RuleSetEnum.SALES_ORDER, _('Sales Orders')), (RuleSetEnum.RETURN_ORDER, _('Return Orders')), + (RuleSetEnum.TRANSFER_ORDER, _('Transfer Orders')), ] # Ruleset names available in the system. @@ -94,6 +98,18 @@ def get_ruleset_models() -> dict: 'django_mailbox_messageattachment', 'django_mailbox_message', ], + RuleSetEnum.BOM: ['part_bomitem', 'part_bomitemsubstitute'], + RuleSetEnum.BUILD: [ + 'part_part', + 'part_partcategory', + 'part_bomitem', + 'part_bomitemsubstitute', + 'build_build', + 'build_builditem', + 'build_buildline', + 'stock_stockitem', + 'stock_stocklocation', + ], RuleSetEnum.PART_CATEGORY: [ 'part_partcategory', 'part_partcategoryparametertemplate', @@ -102,8 +118,6 @@ def get_ruleset_models() -> dict: RuleSetEnum.PART: [ 'part_part', 'part_partpricing', - 'part_bomitem', - 'part_bomitemsubstitute', 'part_partsellpricebreak', 'part_partinternalpricebreak', 'part_parttesttemplate', @@ -120,17 +134,6 @@ def get_ruleset_models() -> dict: 'stock_stockitemtracking', 'stock_stockitemtestresult', ], - RuleSetEnum.BUILD: [ - 'part_part', - 'part_partcategory', - 'part_bomitem', - 'part_bomitemsubstitute', - 'build_build', - 'build_builditem', - 'build_buildline', - 'stock_stockitem', - 'stock_stocklocation', - ], RuleSetEnum.PURCHASE_ORDER: [ 'company_company', 'company_contact', @@ -160,6 +163,11 @@ def get_ruleset_models() -> dict: 'order_returnorderlineitem', 'order_returnorderextraline', ], + RuleSetEnum.TRANSFER_ORDER: [ + 'order_transferorder', + 'order_transferorderallocation', + 'order_transferorderlineitem', + ], } if settings.SITE_MULTI: diff --git a/src/backend/InvenTree/users/serializers.py b/src/backend/InvenTree/users/serializers.py index 0fdd481137..417a863ae3 100644 --- a/src/backend/InvenTree/users/serializers.py +++ b/src/backend/InvenTree/users/serializers.py @@ -11,11 +11,9 @@ from rest_framework import serializers from rest_framework.exceptions import PermissionDenied from InvenTree.serializers import ( - FilterableListSerializer, - FilterableSerializerMethodField, FilterableSerializerMixin, InvenTreeModelSerializer, - enable_filter, + OptionalField, ) from .models import ApiToken, Owner, RuleSet, UserProfile @@ -56,7 +54,6 @@ class RuleSetSerializer(InvenTreeModelSerializer): 'can_delete', ] read_only_fields = ['pk', 'name', 'label', 'group'] - list_serializer_class = FilterableListSerializer class RoleSerializer(InvenTreeModelSerializer): @@ -185,7 +182,6 @@ class UserSerializer(InvenTreeModelSerializer): model = User fields = ['pk', 'username', 'first_name', 'last_name', 'email'] read_only_fields = ['username', 'email'] - list_serializer_class = FilterableListSerializer username = serializers.CharField(label=_('Username'), help_text=_('Username')) @@ -238,8 +234,21 @@ class ApiTokenSerializer(InvenTreeModelSerializer): def validate(self, data): """Validate the data for the serializer.""" + request_user = self.context['request'].user + if not request_user: + raise serializers.ValidationError( + _('User must be authenticated') + ) # pragma: no cover + if 'user' not in data: - data['user'] = self.context['request'].user + data['user'] = request_user + + # Only superusers can create tokens for other users + if data['user'] != request_user and not request_user.is_superuser: + raise serializers.ValidationError( + _('Only a superuser can create a token for another user') + ) + return super().validate(data) user_detail = UserSerializer(source='user', read_only=True) @@ -254,8 +263,9 @@ class GroupSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): model = Group fields = ['pk', 'name', 'permissions', 'roles', 'users'] - permissions = enable_filter( - FilterableSerializerMethodField(allow_null=True, read_only=True), + permissions = OptionalField( + serializer_class=serializers.SerializerMethodField, + serializer_kwargs={'allow_null': True, 'read_only': True}, filter_name='permission_detail', ) @@ -263,16 +273,26 @@ class GroupSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): """Return a list of permissions associated with the group.""" return generate_permission_dict(group.permissions.all()) - roles = enable_filter( - RuleSetSerializer( - source='rule_sets', many=True, read_only=True, allow_null=True - ), + roles = OptionalField( + serializer_class=RuleSetSerializer, + serializer_kwargs={ + 'source': 'rule_sets', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, filter_name='role_detail', prefetch_fields=['rule_sets'], ) - users = enable_filter( - UserSerializer(source='user_set', many=True, read_only=True, allow_null=True), + users = OptionalField( + serializer_class=UserSerializer, + serializer_kwargs={ + 'source': 'user_set', + 'many': True, + 'read_only': True, + 'allow_null': True, + }, filter_name='user_detail', prefetch_fields=['user_set'], ) @@ -306,8 +326,8 @@ class ExtendedUserSerializer(UserSerializer): ) is_staff = serializers.BooleanField( - label=_('Staff'), - help_text=_('Does this user have staff permissions'), + label=_('Administrator'), + help_text=_('Does this user have administrative permissions'), required=False, ) @@ -380,6 +400,9 @@ class MeUserSerializer(ExtendedUserSerializer): but ensures that certain fields are read-only. """ + # 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'] + read_only_fields = [ *ExtendedUserSerializer.Meta.read_only_fields, 'is_active', @@ -389,6 +412,28 @@ class MeUserSerializer(ExtendedUserSerializer): profile = UserProfileSerializer(many=False, read_only=True) + # Redefine the fields from ExtendedUserSerializer, to ensure they are marked as read-only + is_staff = serializers.BooleanField( + label=_('Staff'), + help_text=_('Does this user have staff permissions'), + required=False, + read_only=True, + ) + + is_superuser = serializers.BooleanField( + label=_('Superuser'), + help_text=_('Is this user a superuser'), + required=False, + read_only=True, + ) + + is_active = serializers.BooleanField( + label=_('Active'), + help_text=_('Is this user account active'), + required=False, + read_only=True, + ) + def make_random_password(length=14): """Generate a random password of given length.""" diff --git a/src/backend/InvenTree/users/test_api.py b/src/backend/InvenTree/users/test_api.py index 473b70946b..20cd9488d8 100644 --- a/src/backend/InvenTree/users/test_api.py +++ b/src/backend/InvenTree/users/test_api.py @@ -37,13 +37,14 @@ class UserAPITests(InvenTreeAPITestCase): fields['is_active']['help_text'], 'Is this user account active' ) - self.assertEqual(fields['is_staff']['label'], 'Staff') + self.assertEqual(fields['is_staff']['label'], 'Administrator') self.assertEqual( - fields['is_staff']['help_text'], 'Does this user have staff permissions' + fields['is_staff']['help_text'], + 'Does this user have administrative permissions', ) def test_api_url(self): - """Test the 'api_url attribute in related API endpoints. + """Test the 'api_url' attribute in related API endpoints. Ref: https://github.com/inventree/InvenTree/pull/10182 """ @@ -53,12 +54,16 @@ class UserAPITests(InvenTreeAPITestCase): url = reverse('api-build-list') response = self.options(url) actions = response.data['actions']['POST'] - issued_by = actions['issued_by'] - self.assertEqual(issued_by['pk_field'], 'pk') - self.assertEqual(issued_by['model'], 'user') - self.assertEqual(issued_by['api_url'], reverse('api-user-list')) - self.assertEqual(issued_by['default'], self.user.pk) + issued_by = actions['issued_by'] + self.assertTrue(issued_by['read_only']) + + project_code = actions['project_code'] + self.assertFalse(project_code['read_only']) + self.assertEqual(project_code['type'], 'related field') + self.assertEqual(project_code['model'], 'projectcode') + self.assertEqual(project_code['api_url'], reverse('api-project-code-list')) + self.assertEqual(project_code['pk_field'], 'pk') def test_user_api(self): """Tests for User API endpoints.""" @@ -128,6 +133,19 @@ class UserAPITests(InvenTreeAPITestCase): self.assertIn('Only a superuser can adjust this field', str(response.data)) + # Try again, but with superuser access + self.user.is_superuser = True + self.user.save() + + response = self.post( + url, + data={**data, 'username': 'Superuser', 'is_superuser': True}, + expected_code=201, + ) + + self.assertEqual(response.data['username'], 'Superuser') + self.assertEqual(response.data['is_superuser'], True) + def test_user_detail(self): """Test the UserDetail API endpoint.""" user = User.objects.first() @@ -142,7 +160,7 @@ class UserAPITests(InvenTreeAPITestCase): self.get(url, expected_code=200) # Let's try to update the user - data = {'is_active': False, 'is_staff': False} + data = {'is_active': True, 'is_staff': False} self.patch(url, data=data, expected_code=403) @@ -157,6 +175,26 @@ class UserAPITests(InvenTreeAPITestCase): self.patch(url, data=data, expected_code=200) + # Try to change the "is_superuser" field - only a superuser can do this + data['is_superuser'] = True + response = self.patch(url, data=data, expected_code=403) + + self.assertIn( + 'You do not have permission to perform this action', str(response.data) + ) + + self.user.is_staff = True + self.user.is_superuser = True + self.user.save() + + for val in [True, False]: + data['is_staff'] = True + data['is_superuser'] = val + + response = self.patch(url, data=data, expected_code=200) + self.assertEqual(response.data['is_superuser'], val) + self.assertEqual(response.data['is_staff'], True) + # Try again, but logged out - expect no access to the endpoint self.logout() self.get(url, expected_code=401) @@ -184,8 +222,11 @@ class UserAPITests(InvenTreeAPITestCase): expected_code=200, ) self.assertIn('name', response.data) + self.assertIn('roles', response.data) self.assertIn('permissions', response.data) + self.assertGreater(len(response.data['roles']), 0) + def test_login_redirect(self): """Test login redirect endpoint.""" response = self.get(reverse('api-login-redirect'), expected_code=302) @@ -228,6 +269,71 @@ class UserAPITests(InvenTreeAPITestCase): self.assertEqual(len(data['permissions']), len(perms) + len(build_perms)) + def test_me_endpoint(self): + """Test against the users /me/ endpoint.""" + url = reverse('api-user-me') + + # Test endpoint options + response = self.options(url, expected_code=200) + + # Check that particular fields are present, and have the correct attributes + fields = response.data['actions']['PUT'] + + for name in [ + 'pk', + 'username', + 'email', + 'groups', + 'is_active', + 'is_staff', + 'is_superuser', + ]: + self.assertIn(name, fields) + + for name in ['is_active', 'is_staff', 'is_superuser']: + self.assertTrue(fields[name]['read_only']) + + # Perform a GET request against the endpoint + response = self.get(url, expected_code=200) + + for field in [ + 'pk', + 'username', + 'email', + 'is_active', + 'is_staff', + 'is_superuser', + ]: + self.assertIn(field, response.data) + + # Change their own username + for name in ['Henry', 'Sally']: + response = self.patch(url, data={'username': name}, expected_code=200) + self.assertEqual(response.data['username'], name) + + # Defined starting point for the user + for v in [True, False]: + self.user.is_staff = v + self.user.is_superuser = v + self.user.save() + + for key in ['is_staff', 'is_superuser']: + for val in [True, False]: + response = self.patch(url, data={key: val}, expected_code=200) + + # Check that the field was *NOT CHANGED* + self.assertEqual(response.data[key], v) + + # Ensure we cannot change the "is_active" field either + response = self.patch(url, data={'is_active': False}, expected_code=200) + self.assertEqual(response.data['is_active'], True) + + self.user.is_active = False + self.user.save() + + # User cannot fetch their own details if they are not active + response = self.get(url, expected_code=401) + class SuperuserAPITests(InvenTreeAPITestCase): """Tests for user API endpoints that require superuser rights.""" @@ -244,7 +350,7 @@ class SuperuserAPITests(InvenTreeAPITestCase): resp = self.put(url, {'password': 1}, expected_code=400) self.assertContains(resp, 'This password is too short', status_code=400) - # now with overwerite + # now with overwrite resp = self.put( url, {'password': 1, 'override_warning': True}, expected_code=200 ) @@ -258,6 +364,8 @@ class SuperuserAPITests(InvenTreeAPITestCase): class UserTokenTests(InvenTreeAPITestCase): """Tests for user token functionality.""" + fixtures = ['users'] + def test_token_generation(self): """Test user token generation.""" url = reverse('api-token') @@ -396,8 +504,30 @@ class UserTokenTests(InvenTreeAPITestCase): self.client.logout() self.get(reverse('api-token'), expected_code=401) + def test_token_security(self): + """Test that token generation is only available to users with the correct permissions.""" + url = reverse('api-token-list') -class GroupDetialTests(InvenTreeAPITestCase): + # Try to generate a token for a different user (should fail) + response = self.post(url, data={'name': 'test', 'user': 1}, expected_code=400) + self.assertIn( + 'Only a superuser can create a token for another user', str(response.data) + ) + + # there should be no tokens created + self.assertEqual(ApiToken.objects.count(), 0) + + # now with superuser permissions + self.user.is_superuser = True + self.user.save() + + response = self.post(url, data={'name': 'test', 'user': 1}, expected_code=201) + self.assertIn('token', response.data) + + self.assertEqual(ApiToken.objects.count(), 1) + + +class GroupDetailTests(InvenTreeAPITestCase): """Tests for the GroupDetail API endpoint.""" fixtures = ['users'] diff --git a/src/backend/InvenTree/web/tests.py b/src/backend/InvenTree/web/tests.py index bed9ed43f6..04a25b73a1 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('
+ { + 'This means that the InvenTree UI library version is incompatible with this plugin version.' + } +
+ Plugin Version: {INVENTREE_PLUGIN_VERSION} +
+ UI Version: {context?.version?.inventree || 'unknown'} +
+ + ); + } + + return context?.tables.renderTable({ + url: url, + tableState: tableState, + tableData: tableData, + columns: columns, + props: props, + api: context.api, + navigate: context.navigate + }); +} diff --git a/src/frontend/lib/components/RowActions.tsx b/src/frontend/lib/components/RowActions.tsx index 464744277c..ff2ad44c40 100644 --- a/src/frontend/lib/components/RowActions.tsx +++ b/src/frontend/lib/components/RowActions.tsx @@ -139,8 +139,8 @@ export function RowActions({ aria-label={`row-action-menu-${index ?? ''}`} onClick={openMenu} disabled={disabled} - variant='subtle' - color='gray' + variant='transparent' + size='sm' > diff --git a/src/frontend/src/components/items/StylishText.tsx b/src/frontend/lib/components/StylishText.tsx similarity index 100% rename from src/frontend/src/components/items/StylishText.tsx rename to src/frontend/lib/components/StylishText.tsx diff --git a/src/frontend/src/tables/ColumnSelect.tsx b/src/frontend/lib/components/TableColumnSelect.tsx similarity index 100% rename from src/frontend/src/tables/ColumnSelect.tsx rename to src/frontend/lib/components/TableColumnSelect.tsx diff --git a/src/frontend/src/components/nav/DetailDrawer.css.ts b/src/frontend/lib/components/nav/DetailDrawer.css.ts similarity index 100% rename from src/frontend/src/components/nav/DetailDrawer.css.ts rename to src/frontend/lib/components/nav/DetailDrawer.css.ts diff --git a/src/frontend/src/components/nav/DetailDrawer.tsx b/src/frontend/lib/components/nav/DetailDrawer.tsx similarity index 89% rename from src/frontend/src/components/nav/DetailDrawer.tsx rename to src/frontend/lib/components/nav/DetailDrawer.tsx index dcc7d77e6a..f8edbe2aec 100644 --- a/src/frontend/src/components/nav/DetailDrawer.tsx +++ b/src/frontend/lib/components/nav/DetailDrawer.tsx @@ -4,10 +4,11 @@ import { useCallback, useMemo } from 'react'; import { Link, Route, Routes, useNavigate, useParams } from 'react-router-dom'; import type { To } from 'react-router-dom'; -import type { UiSizeType } from '@lib/types/Core'; +import type { UiSizeType } from '../../types/Core'; + import { useShallow } from 'zustand/react/shallow'; -import { useLocalState } from '../../states/LocalState'; -import { StylishText } from '../items/StylishText'; +import { useLocalLibState } from '../../states/LocalLibState'; +import { StylishText } from '../StylishText'; import * as classes from './DetailDrawer.css'; /** @@ -25,7 +26,7 @@ export interface DrawerProps { closeOnEscape?: boolean; } -function DetailDrawerComponent({ +export function DetailDrawerComponent({ title, position = 'right', size, @@ -38,7 +39,7 @@ function DetailDrawerComponent({ const content = renderContent(id); const opened = useMemo(() => !!id && !!content, [id, content]); - const [detailDrawerStack, addDetailDrawer] = useLocalState( + const [detailDrawerStack, addDetailDrawer] = useLocalLibState( useShallow((state) => [state.detailDrawerStack, state.addDetailDrawer]) ); @@ -91,7 +92,7 @@ export function DetailDrawerLink({ to, text }: Readonly<{ to: To; text: string }>) { - const addDetailDrawer = useLocalState( + const addDetailDrawer = useLocalLibState( useShallow((state) => state.addDetailDrawer) ); diff --git a/src/frontend/lib/enums/ApiEndpoints.tsx b/src/frontend/lib/enums/ApiEndpoints.tsx index e7adf3f0b8..cfb6e5e498 100644 --- a/src/frontend/lib/enums/ApiEndpoints.tsx +++ b/src/frontend/lib/enums/ApiEndpoints.tsx @@ -12,12 +12,13 @@ export enum ApiEndpoints { // User API endpoints user_list = 'user/', user_set_password = 'user/:id/set-password/', - user_me = 'user/me/', - user_profile = 'user/profile/', - user_roles = 'user/roles/', - user_token = 'user/token/', user_tokens = 'user/tokens/', user_simple_login = 'email/generate/', + // Individual user endpoints + user_me_profile = 'user/me/profile/', + user_me_roles = 'user/me/roles/', + user_me_token = 'user/me/token/', + user_me = 'user/me/', // User auth endpoints auth_base = '/auth/', @@ -64,7 +65,7 @@ export enum ApiEndpoints { content_type_list = 'contenttype/', icons = 'icons/', selectionlist_list = 'selection/', - selectionlist_detail = 'selection/:id/', + selectionentry_list = 'selection/:id/entry/', // Barcode API endpoints barcode = 'barcode/', @@ -153,6 +154,7 @@ export enum ApiEndpoints { stock_merge = 'stock/merge/', stock_assign = 'stock/assign/', stock_status = 'stock/status/', + stock_convert = 'stock/:id/convert/', stock_install = 'stock/:id/install/', stock_uninstall = 'stock/:id/uninstall/', stock_serialize = 'stock/:id/serialize/', @@ -197,6 +199,17 @@ export enum ApiEndpoints { return_order_line_list = 'order/ro-line/', return_order_extra_line_list = 'order/ro-extra-line/', + transfer_order_list = 'order/transfer-order/', + transfer_order_issue = 'order/transfer-order/:id/issue/', + transfer_order_hold = 'order/transfer-order/:id/hold/', + transfer_order_cancel = 'order/transfer-order/:id/cancel/', + transfer_order_complete = 'order/transfer-order/:id/complete/', + transfer_order_allocate = 'order/transfer-order/:id/allocate/', + transfer_order_allocate_serials = 'order/transfer-order/:id/allocate-serials/', + + transfer_order_line_list = 'order/transfer-order-line/', + transfer_order_allocation_list = 'order/transfer-order-allocation/', + // Template API endpoints label_list = 'label/template/', label_print = 'label/print/', diff --git a/src/frontend/lib/enums/ModelInformation.tsx b/src/frontend/lib/enums/ModelInformation.tsx index 6f93a1ebeb..63aeb6dff5 100644 --- a/src/frontend/lib/enums/ModelInformation.tsx +++ b/src/frontend/lib/enums/ModelInformation.tsx @@ -186,6 +186,7 @@ export const ModelInformationDict: ModelDict = { label_multiple: () => t`Sales Order Shipments`, url_overview: '/sales/index/shipments', url_detail: '/sales/shipment/:pk/', + admin_url: '/order/salesordershipment/', api_endpoint: ApiEndpoints.sales_order_shipment_list, supports_barcode: true, icon: 'shipment' @@ -206,6 +207,22 @@ export const ModelInformationDict: ModelDict = { api_endpoint: ApiEndpoints.return_order_line_list, icon: 'return_orders' }, + transferorder: { + label: () => t`Transfer Order`, + label_multiple: () => t`Transfer Orders`, + url_overview: '/stock/location/index/transfer-orders', + url_detail: '/stock/transfer-order/:pk/', + api_endpoint: ApiEndpoints.transfer_order_list, + admin_url: '/order/transferorder/', + supports_barcode: true, + icon: 'transfer_orders' + }, + transferorderlineitem: { + label: () => t`Transfer Order Line Item`, + label_multiple: () => t`Transfer Order Line Items`, + api_endpoint: ApiEndpoints.transfer_order_line_list, + icon: 'transfer-orders' + }, address: { label: () => t`Address`, label_multiple: () => t`Addresses`, @@ -287,6 +304,13 @@ export const ModelInformationDict: ModelDict = { api_endpoint: ApiEndpoints.selectionlist_list, icon: 'list_details' }, + selectionentry: { + label: () => t`Selection Entry`, + label_multiple: () => t`Selection Entries`, + url_overview: '/settings/admin/part-parameters', + api_endpoint: ApiEndpoints.selectionentry_list, + icon: 'list_details' + }, error: { label: () => t`Error`, label_multiple: () => t`Errors`, diff --git a/src/frontend/lib/enums/ModelType.tsx b/src/frontend/lib/enums/ModelType.tsx index 57aa1b7205..80c436b1b1 100644 --- a/src/frontend/lib/enums/ModelType.tsx +++ b/src/frontend/lib/enums/ModelType.tsx @@ -24,6 +24,8 @@ export enum ModelType { salesordershipment = 'salesordershipment', returnorder = 'returnorder', returnorderlineitem = 'returnorderlineitem', + transferorder = 'transferorder', + transferorderlineitem = 'transferorderlineitem', importsession = 'importsession', address = 'address', contact = 'contact', @@ -35,5 +37,19 @@ export enum ModelType { pluginconfig = 'pluginconfig', contenttype = 'contenttype', selectionlist = 'selectionlist', + selectionentry = 'selectionentry', error = 'error' } + +export enum PluginPanelKey { + // settings / admin + admincenter = 'admincenter', + systemsettings = 'systemsettings', + usersettings = 'usersettings', + // generic + core = 'core', + // landing pages + purchasing = 'purchasing', + sales = 'sales', + manufacturing = 'manufacturing' +} diff --git a/src/frontend/lib/enums/Roles.tsx b/src/frontend/lib/enums/Roles.tsx index efa6c4a04b..3d7ff9c78b 100644 --- a/src/frontend/lib/enums/Roles.tsx +++ b/src/frontend/lib/enums/Roles.tsx @@ -5,11 +5,13 @@ import { t } from '@lingui/core/macro'; */ export enum UserRoles { admin = 'admin', + bom = 'bom', build = 'build', part = 'part', part_category = 'part_category', purchase_order = 'purchase_order', return_order = 'return_order', + transfer_order = 'transfer_order', sales_order = 'sales_order', stock = 'stock', stock_location = 'stock_location' @@ -39,6 +41,8 @@ export function userRoleLabel(role: UserRoles): string { return t`Purchase Orders`; case UserRoles.return_order: return t`Return Orders`; + case UserRoles.transfer_order: + return t`Transfer Orders`; case UserRoles.sales_order: return t`Sales Orders`; case UserRoles.stock: diff --git a/src/frontend/lib/functions/Forms.tsx b/src/frontend/lib/functions/Forms.tsx new file mode 100644 index 0000000000..78ad55ce2e --- /dev/null +++ b/src/frontend/lib/functions/Forms.tsx @@ -0,0 +1,47 @@ +import type { ApiEndpoints } from '../enums/ApiEndpoints'; +import type { PathParams } from '../types/Core'; +import type { ApiFormFieldSet, ApiFormFieldType } from '../types/Forms'; +import { apiUrl } from './Api'; + +/** + * Construct an API url from the provided ApiFormProps object + */ +export function constructFormUrl( + url: ApiEndpoints | string, + pk?: string | number, + pathParams?: PathParams, + queryParams?: URLSearchParams +): string { + let formUrl = apiUrl(url, pk, pathParams); + + if (queryParams) { + formUrl += `?${queryParams.toString()}`; + } + + return formUrl; +} + +export type NestedDict = { [key: string]: string | number | NestedDict }; + +export function mapFields( + fields: ApiFormFieldSet, + fieldFunction: (path: string, value: ApiFormFieldType, key: string) => any, + _path?: string +): NestedDict { + const res: NestedDict = {}; + + for (const [k, v] of Object.entries(fields)) { + const path = _path ? `${_path}.${k}` : k; + let value: any; + + if (v.field_type === 'nested object' && v.children) { + value = mapFields(v.children, fieldFunction, path); + } else { + value = fieldFunction(path, v, k); + } + + if (value !== undefined) res[k] = value; + } + + return res; +} diff --git a/src/frontend/lib/functions/Notification.tsx b/src/frontend/lib/functions/Notification.tsx new file mode 100644 index 0000000000..8e16570e7c --- /dev/null +++ b/src/frontend/lib/functions/Notification.tsx @@ -0,0 +1,50 @@ +import { t } from '@lingui/core/macro'; +import { notifications } from '@mantine/notifications'; + +/** + * Show a notification that the feature is not yet implemented + */ +export function notYetImplemented() { + notifications.hide('not-implemented'); + + notifications.show({ + title: t`Not implemented`, + message: t`This feature is not yet implemented`, + color: 'red', + id: 'not-implemented' + }); +} + +/** + * Show a notification that the user does not have permission to perform the action + */ +export function permissionDenied() { + notifications.show({ + title: t`Permission Denied`, + message: t`You do not have permission to perform this action`, + color: 'red' + }); +} + +/** + * Display a notification on an invalid return code + */ +export function invalidResponse(returnCode: number) { + // TODO: Specific return code messages + notifications.show({ + title: t`Invalid Return Code`, + message: t`Server returned status ${returnCode}`, + color: 'red' + }); +} + +/** + * Display a notification on timeout + */ +export function showTimeoutNotification() { + notifications.show({ + title: t`Timeout`, + message: t`The request timed out`, + color: 'red' + }); +} diff --git a/src/frontend/src/functions/tables.tsx b/src/frontend/lib/functions/String.tsx similarity index 100% rename from src/frontend/src/functions/tables.tsx rename to src/frontend/lib/functions/String.tsx diff --git a/src/frontend/lib/hooks/MonitorBackgroundTask.tsx b/src/frontend/lib/hooks/MonitorBackgroundTask.tsx new file mode 100644 index 0000000000..db130b6be4 --- /dev/null +++ b/src/frontend/lib/hooks/MonitorBackgroundTask.tsx @@ -0,0 +1,118 @@ +import { useDocumentVisibility } from '@mantine/hooks'; +import { notifications, showNotification } from '@mantine/notifications'; +import { + IconCircleCheck, + IconCircleX, + IconExclamationCircle +} from '@tabler/icons-react'; +import { type QueryClient, useQuery } from '@tanstack/react-query'; +import type { AxiosInstance } from 'axios'; +import { useEffect, useState } from 'react'; +import { ApiEndpoints } from '../enums/ApiEndpoints'; +import { apiUrl } from '../functions/Api'; + +export type MonitorBackgroundTaskProps = { + api: AxiosInstance; + queryClient?: QueryClient; + title?: string; + message: string; + errorMessage?: string; + successMessage?: string; + failureMessage?: string; + taskId?: string; + onSuccess?: () => void; + onFailure?: () => void; + onComplete?: () => void; + onError?: (error: Error) => void; +}; + +/** + * Hook for monitoring a background task running on the server + */ +export default function useMonitorBackgroundTask( + props: MonitorBackgroundTaskProps +) { + const visibility = useDocumentVisibility(); + + const [tracking, setTracking] = useState(false); + + useEffect(() => { + if (!!props.taskId) { + setTracking(true); + showNotification({ + id: `background-task-${props.taskId}`, + title: props.title, + message: props.message, + loading: true, + autoClose: false, + withCloseButton: false + }); + } else { + setTracking(false); + } + }, [props.taskId]); + + useQuery( + { + enabled: !!props.taskId && tracking && visibility === 'visible', + refetchInterval: 500, + queryKey: ['background-task', props.taskId], + queryFn: () => + props.api + .get(apiUrl(ApiEndpoints.task_overview, props.taskId)) + .then((response) => { + const data = response?.data ?? {}; + + if (data.complete) { + setTracking(false); + props.onComplete?.(); + + notifications.update({ + id: `background-task-${props.taskId}`, + title: props.title, + loading: false, + color: data.success ? 'green' : 'red', + message: response.data?.success + ? (props.successMessage ?? props.message) + : (props.failureMessage ?? props.message), + icon: response.data?.success ? ( + + ) : ( + + ), + autoClose: 1000, + withCloseButton: true + }); + + if (data.success) { + props.onSuccess?.(); + } else { + props.onFailure?.(); + } + } + + return response; + }) + .catch((error) => { + console.error( + `Error fetching background task status for task ${props.taskId}:`, + error + ); + setTracking(false); + props.onError?.(error); + + notifications.update({ + id: `background-task-${props.taskId}`, + title: props.title, + loading: false, + color: 'red', + message: props.errorMessage ?? props.message, + icon: , + autoClose: 5000, + withCloseButton: true + }); + }) + }, + props.queryClient + ); +} diff --git a/src/frontend/lib/hooks/MonitorDataOutput.tsx b/src/frontend/lib/hooks/MonitorDataOutput.tsx new file mode 100644 index 0000000000..dd66758416 --- /dev/null +++ b/src/frontend/lib/hooks/MonitorDataOutput.tsx @@ -0,0 +1,124 @@ +import { t } from '@lingui/core/macro'; +import { useDocumentVisibility } from '@mantine/hooks'; +import { notifications, showNotification } from '@mantine/notifications'; +import { IconCircleCheck, IconExclamationCircle } from '@tabler/icons-react'; +import { type QueryClient, useQuery } from '@tanstack/react-query'; +import type { AxiosInstance } from 'axios'; +import { useEffect, useState } from 'react'; +import { ProgressBar } from '../components/ProgressBar'; +import { ApiEndpoints } from '../enums/ApiEndpoints'; +import { apiUrl } from '../functions/Api'; + +export type MonitorDataOutputProps = { + api: AxiosInstance; + queryClient?: QueryClient; + title: string; + hostname?: string; + id?: number; +}; + +/** + * Hook for monitoring a data output process running on the server + */ +export default function useMonitorDataOutput(props: MonitorDataOutputProps) { + const visibility = useDocumentVisibility(); + + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!!props.id) { + setLoading(true); + showNotification({ + id: `data-output-${props.id}`, + title: props.title, + loading: true, + autoClose: false, + withCloseButton: false, + message: + }); + } else setLoading(false); + }, [props.id, props.title]); + + useQuery( + { + enabled: !!props.id && loading && visibility === 'visible', + refetchInterval: 500, + queryKey: ['data-output', props.id, props.title], + queryFn: () => + props.api + .get(apiUrl(ApiEndpoints.data_output, props.id)) + .then((response) => { + const data = response?.data ?? {}; + + if (!!data.errors || !!data.error) { + setLoading(false); + + const error: string = + data?.error ?? data?.errors?.error ?? t`Process failed`; + + notifications.update({ + id: `data-output-${props.id}`, + loading: false, + icon: , + autoClose: 2500, + title: props.title, + message: error, + color: 'red' + }); + } else if (data.complete) { + setLoading(false); + notifications.update({ + id: `data-output-${props.id}`, + loading: false, + autoClose: 2500, + title: props.title, + message: t`Process completed successfully`, + color: 'green', + icon: + }); + + if (data.output) { + const url = data.output; + const base = props.hostname ?? window.location.origin; + + const downloadUrl = new URL(url, base); + + window.open(downloadUrl.toString(), '_blank'); + } + } else { + notifications.update({ + id: `data-output-${props.id}`, + loading: true, + autoClose: false, + withCloseButton: false, + message: ( + 0} + animated + /> + ) + }); + } + + return data; + }) + .catch((error: Error) => { + console.error('Error in useMonitorDataOutput:', error); + setLoading(false); + notifications.update({ + id: `data-output-${props.id}`, + loading: false, + autoClose: 2500, + title: props.title, + message: error.message || t`Process failed`, + color: 'red' + }); + return {}; + }) + }, + props.queryClient + ); +} diff --git a/src/frontend/src/hooks/UseFilterSet.tsx b/src/frontend/lib/hooks/UseFilterSet.tsx similarity index 69% rename from src/frontend/src/hooks/UseFilterSet.tsx rename to src/frontend/lib/hooks/UseFilterSet.tsx index 9d0300cb46..52749f0c54 100644 --- a/src/frontend/src/hooks/UseFilterSet.tsx +++ b/src/frontend/lib/hooks/UseFilterSet.tsx @@ -1,8 +1,8 @@ -import type { FilterSetState, TableFilter } from '@lib/types/Filters'; import { useLocalStorage } from '@mantine/hooks'; -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; +import type { FilterSetState, TableFilter } from '../types/Filters'; -export function useFilterSet( +export default function useFilterSet( filterKey: string, initialFilters?: TableFilter[] ): FilterSetState { @@ -16,15 +16,15 @@ export function useFilterSet( getInitialValueInEffect: false }); - const activeFilters: TableFilter[] = useMemo(() => { + useEffect(() => { if (storedFilters == null) { - // If there are no stored filters, set initial values - const filters = initialFilters || []; - setStoredFilters(filters); - return filters; + setStoredFilters(initialFilters || []); } - return storedFilters || []; - }, [storedFilters]); + }, [storedFilters, initialFilters, setStoredFilters]); + + const activeFilters: TableFilter[] = useMemo(() => { + return storedFilters ?? initialFilters ?? []; + }, [storedFilters, initialFilters]); // Callback to clear all active filters from the table const clearActiveFilters = useCallback(() => { diff --git a/src/frontend/src/hooks/UseTable.tsx b/src/frontend/lib/hooks/UseTable.tsx similarity index 86% rename from src/frontend/src/hooks/UseTable.tsx rename to src/frontend/lib/hooks/UseTable.tsx index 49a2c50569..52bdd6afa4 100644 --- a/src/frontend/src/hooks/UseTable.tsx +++ b/src/frontend/lib/hooks/UseTable.tsx @@ -1,10 +1,9 @@ import { randomId } from '@mantine/hooks'; import { useCallback, useMemo, useState } from 'react'; -import { useSearchParams } from 'react-router-dom'; -import type { FilterSetState, TableFilter } from '@lib/types/Filters'; -import type { TableState } from '@lib/types/Tables'; -import { useFilterSet } from './UseFilterSet'; +import type { FilterSetState, TableFilter } from '../types/Filters'; +import type { TableState } from '../types/Tables'; +import useFilterSet from './UseFilterSet'; export type TableStateExtraProps = { idAccessor?: string; @@ -17,7 +16,7 @@ export type TableStateExtraProps = { * Refer to the TableState type definition for more information. */ -export function useTable( +export default function useTable( tableName: string, tableProps: TableStateExtraProps = { idAccessor: 'pk', @@ -29,13 +28,6 @@ export function useTable( return `${tableName.replaceAll('-', '')}-${randomId()}`; } - // Extract URL query parameters (e.g. ?active=true&overdue=false) - const [queryFilters, setQueryFilters] = useSearchParams(); - - const clearQueryFilters = useCallback(() => { - setQueryFilters({}); - }, []); - const [tableKey, setTableKey] = useState(generateTableName()); // Callback used to refresh (reload) the table @@ -133,9 +125,6 @@ export function useTable( isLoading, setIsLoading, filterSet, - queryFilters, - setQueryFilters, - clearQueryFilters, expandedRecords, setExpandedRecords, isRowExpanded, diff --git a/src/frontend/lib/index.ts b/src/frontend/lib/index.ts index 17e7e20f36..3642e341ba 100644 --- a/src/frontend/lib/index.ts +++ b/src/frontend/lib/index.ts @@ -15,10 +15,34 @@ export { UserRoles, UserPermissions } from './enums/Roles'; export type { InvenTreePluginContext, InvenTreeFormsContext, + InvenTreeTablesContext, + ImporterDrawerContext, PluginVersion, StockAdjustmentFormsContext } from './types/Plugins'; -export type { RowAction, RowViewProps } from './types/Tables'; + +export type { + PanelIndicatorType, + PanelType, + PanelGroupType +} from './types/Panel'; + +export type { + RowAction, + RowViewProps, + TableColumn, + TableColumnProps, + TableState, + InvenTreeTableProps, + InvenTreeTableRenderProps +} from './types/Tables'; + +export type { + TableFilterChoice, + TableFilterType, + TableFilter, + FilterSetState +} from './types/Filters'; export type { ApiFormFieldChoice, @@ -42,6 +66,14 @@ export { getDetailUrl, navigateToLink } from './functions/Navigation'; + +export { + notYetImplemented, + permissionDenied, + invalidResponse, + showTimeoutNotification +} from './functions/Notification'; + export { checkPluginVersion, initPlugin @@ -53,16 +85,32 @@ export { formatFileSize } from './functions/Formatting'; +export { + constructFormUrl, + mapFields, + type NestedDict +} from './functions/Forms'; + +export { + shortenString, + hashString +} from './functions/String'; + // Common UI components export { ActionButton, type ActionButtonProps } from './components/ActionButton'; export { AddItemButton } from './components/AddItemButton'; +export { Boundary, DefaultFallback } from './components/Boundary'; export { ButtonMenu } from './components/ButtonMenu'; +export { CopyButton } from './components/CopyButton'; +export { CopyableCell } from './components/CopyableCell'; export { ProgressBar } from './components/ProgressBar'; export { PassFailButton, YesNoButton } from './components/YesNoButton'; export { SearchInput } from './components/SearchInput'; +export { TableColumnSelect } from './components/TableColumnSelect'; +export { default as InvenTreeTable } from './components/InvenTreeTable'; export { RowViewAction, RowDuplicateAction, @@ -71,3 +119,36 @@ export { RowCancelAction, RowActions } from './components/RowActions'; + +// Shared hooks +export { + default as useMonitorDataOutput, + type MonitorDataOutputProps +} from './hooks/MonitorDataOutput'; + +export { + default as useMonitorBackgroundTask, + type MonitorBackgroundTaskProps +} from './hooks/MonitorBackgroundTask'; + +export { default as useFilterSet } from './hooks/UseFilterSet'; + +export { + default as useTable, + type TableStateExtraProps +} from './hooks/UseTable'; + +export { + type DrawerProps, + DetailDrawer, + DetailDrawerLink, + DetailDrawerComponent +} from './components/nav/DetailDrawer'; +export { StylishText } from './components/StylishText'; + +// State management +export { + type StoredTableStateProps, + useStoredTableState +} from './states/StoredTableState'; +export { useLocalLibState } from './states/LocalLibState'; diff --git a/src/frontend/lib/states/LocalLibState.tsx b/src/frontend/lib/states/LocalLibState.tsx new file mode 100644 index 0000000000..76431c8d79 --- /dev/null +++ b/src/frontend/lib/states/LocalLibState.tsx @@ -0,0 +1,23 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; + +export const useLocalLibState = create()( + persist( + (set, get) => ({ + detailDrawerStack: 0, + addDetailDrawer: (value) => { + set({ + detailDrawerStack: + value === false ? 0 : get().detailDrawerStack + value + }); + } + }), + { + name: 'session-settings-inventreedb_lib' + } + ) +); +export interface LocalLibStateProps { + detailDrawerStack: number; + addDetailDrawer: (value: number | false) => void; +} diff --git a/src/frontend/src/states/StoredTableState.tsx b/src/frontend/lib/states/StoredTableState.tsx similarity index 98% rename from src/frontend/src/states/StoredTableState.tsx rename to src/frontend/lib/states/StoredTableState.tsx index 7d9519dc09..f0e6c40e09 100644 --- a/src/frontend/src/states/StoredTableState.tsx +++ b/src/frontend/lib/states/StoredTableState.tsx @@ -13,7 +13,7 @@ const DEFAULT_PAGE_SIZE: number = 25; * - columnNames: An object mapping table keys to arrays of column names. * - sorting: An object mapping table keys to sorting configurations. */ -interface StoredTableStateProps { +export interface StoredTableStateProps { pageSize: number; setPageSize: (size: number) => void; tableSorting: Record; diff --git a/src/frontend/lib/states/types.tsx b/src/frontend/lib/states/types.tsx new file mode 100644 index 0000000000..475ab0fd13 --- /dev/null +++ b/src/frontend/lib/states/types.tsx @@ -0,0 +1,7 @@ +import type { ReactNode } from 'react'; +import type { InstanceRenderInterface } from '../types/Rendering'; + +export type setRenderProps = ( + model: string, + renderer: (props: Readonly) => ReactNode +) => void; diff --git a/src/frontend/lib/types/Forms.tsx b/src/frontend/lib/types/Forms.tsx index 1bc3dc62f3..83e78a8e1a 100644 --- a/src/frontend/lib/types/Forms.tsx +++ b/src/frontend/lib/types/Forms.tsx @@ -37,7 +37,6 @@ export type ApiFormFieldHeader = { * - All other attributes are optional, and may be provided by the API * - However, they can be overridden by the user * - * @param name : The name of the field * @param label : The label to display for the field * @param value : The value of the field * @param default : The default value of the field @@ -46,16 +45,22 @@ export type ApiFormFieldHeader = { * @param api_url : The API endpoint to fetch data from (for related fields) * @param pk_field : The primary key field for the related field (default = "pk") * @param model : The model to use for related fields + * @param custom_model : Optional custom model name (plugins may register renderers for custom models) + * @param modelRenderer : Optional function to render the related model instance (for related fields) * @param filters : Optional API filters to apply to related fields + * @param child: Optional definition of a child field (for nested objects) + * @param children: Optional definitions of child fields (for nested objects with multiple fields) * @param required : Whether the field is required - * @param allow_null: Whether the field allows null values - * @param allow_blank: Whether the field allows blank values + * @param error : Optional error message to display * @param hidden : Whether the field is hidden * @param disabled : Whether the field is disabled - * @param error : Optional error message to display + * @param allow_null: Whether the field allows null values + * @param allow_blank: Whether the field allows blank values * @param exclude : Whether to exclude the field from the submitted data + * @param read_only : Whether the field is read-only * @param placeholder : The placeholder text to display * @param placeholderAutofill: Whether to allow auto-filling of the placeholder value + * @param addCreateFields : Fields to display when creating a new related object (for related fields) * @param description : The description to display for the field * @param preFieldContent : Content to render before the field * @param postFieldContent : Content to render after the field @@ -63,11 +68,12 @@ export type ApiFormFieldHeader = { * @param rightSection : Content to render in the right section of the field * @param autoFill: Whether to automatically fill the field with data from the API * @param autoFillFilters: Optional filters to apply when auto-filling the field + * @param adjustValue : Callback function to adjust the value of the field before it is sent to the API * @param onValueChange : Callback function to call when the field value changes * @param adjustFilters : Callback function to adjust the filters for a related field before a query is made - * @param adjustValue : Callback function to adjust the value of the field before it is sent to the API * @param addRow : Callback function to add a new row to a table field - * @param onKeyDown : Callback function to get which key was pressed in the form to handle submission on enter + * @param headers : Optional definitions of table headers (for table fields) + * @param singleFetchFunction : Optional function to fetch a single value for this field (used for fetching the initial value when editing an existing object) */ export type ApiFormFieldType = { label?: string; @@ -96,6 +102,7 @@ export type ApiFormFieldType = { api_url?: string; pk_field?: string; model?: ModelType; + custom_model?: string; modelRenderer?: (instance: any) => ReactNode; filters?: any; child?: ApiFormFieldType; @@ -113,6 +120,7 @@ export type ApiFormFieldType = { placeholderAutofill?: boolean; placeholderWarningCompare?: string | number; placeholderWarning?: string; + addCreateFields?: ApiFormFieldSet; description?: string; preFieldContent?: JSX.Element; postFieldContent?: JSX.Element; @@ -126,6 +134,7 @@ export type ApiFormFieldType = { addRow?: () => any; headers?: ApiFormFieldHeader[]; depends_on?: string[]; + singleFetchFunction?: (value: any) => Promise | null; }; export type ApiFormFieldSet = Record; @@ -180,6 +189,8 @@ export interface ApiFormProps { follow?: boolean; actions?: ApiFormAction[]; timeout?: number; + keepOpenOption?: boolean; + onKeepOpenChange?: (keepOpen: boolean) => void; } /** diff --git a/src/frontend/lib/types/Icons.tsx b/src/frontend/lib/types/Icons.tsx index c06cb197c5..ea03bfba0c 100644 --- a/src/frontend/lib/types/Icons.tsx +++ b/src/frontend/lib/types/Icons.tsx @@ -1,8 +1,6 @@ -import type { Icon, IconProps } from '@tabler/icons-react'; +import type { IconCircle } from '@tabler/icons-react'; -export type TablerIconType = React.ForwardRefExoticComponent< - Omit & React.RefAttributes ->; +export type TablerIconType = typeof IconCircle; export type InvenTreeIconType = { [key: string]: TablerIconType; diff --git a/src/frontend/src/components/panels/Panel.tsx b/src/frontend/lib/types/Panel.tsx similarity index 59% rename from src/frontend/src/components/panels/Panel.tsx rename to src/frontend/lib/types/Panel.tsx index 2fafd2283b..5e3bd103d6 100644 --- a/src/frontend/src/components/panels/Panel.tsx +++ b/src/frontend/lib/types/Panel.tsx @@ -1,5 +1,8 @@ import type { ReactNode } from 'react'; +// The type of indicator dot to be shown against a panel +export type PanelIndicatorType = 'info' | 'warning' | 'danger' | null; + /** * Type used to specify a single panel in a panel group */ @@ -8,13 +11,17 @@ export type PanelType = { label: string; controls?: ReactNode; icon?: ReactNode; - notification_dot?: 'info' | 'warning' | 'danger' | null; + notification_dot?: PanelIndicatorType | (() => Promise); content?: ReactNode; hidden?: boolean; disabled?: boolean; showHeadline?: boolean; + supportsDirty?: boolean; }; +/** + * Type used to specify a group of panels + */ export type PanelGroupType = { id: string; label: string; diff --git a/src/frontend/lib/types/Plugins.tsx b/src/frontend/lib/types/Plugins.tsx index cc10083b6e..2038b1f297 100644 --- a/src/frontend/lib/types/Plugins.tsx +++ b/src/frontend/lib/types/Plugins.tsx @@ -2,17 +2,26 @@ import type { I18n } from '@lingui/core'; import type { MantineColorScheme, MantineTheme } from '@mantine/core'; import type { QueryClient } from '@tanstack/react-query'; import type { AxiosInstance } from 'axios'; +import type { JSX } from 'react'; import type { NavigateFunction } from 'react-router-dom'; import type { ModelDict } from '../enums/ModelInformation'; import type { ModelType } from '../enums/ModelType'; +import type { setRenderProps } from '../states/types'; import type { ApiFormModalProps, + ApiFormProps, BulkEditApiFormModalProps, StockOperationProps } from './Forms'; import type { UseModalReturn } from './Modals'; -import type { RenderInstanceProps } from './Rendering'; +import type { + RemoteInstanceProps, + RenderInlineModelProps, + RenderInstanceProps, + ThumbnailProps +} from './Rendering'; import type { SettingsStateProps } from './Settings'; +import type { InvenTreeTableRenderProps } from './Tables'; import type { UserStateProps } from './User'; export interface PluginProps { @@ -45,27 +54,43 @@ export type InvenTreeFormsContext = { create: (props: ApiFormModalProps) => UseModalReturn; delete: (props: ApiFormModalProps) => UseModalReturn; edit: (props: ApiFormModalProps) => UseModalReturn; + editApiForm: (props: { id?: string; props: ApiFormProps }) => React.ReactNode; stockActions: StockAdjustmentFormsContext; }; +export type InvenTreeTablesContext> = { + renderTable: (props: InvenTreeTableRenderProps) => React.ReactNode; +}; + +export type ImporterDrawerContext = { + open: (sessionId: number, options?: { onClose?: () => void }) => void; + close: () => void; + isOpen: () => boolean; + sessionId: () => number | null; +}; + /** * A set of properties which are passed to a plugin, * for rendering an element in the user interface. * * @param version - The version of the running InvenTree software stack * @param api - The Axios API instance (see ../states/ApiState.tsx) + * @param queryClient - The Tanstack QueryClient instance (see ../states/QueryState.tsx) * @param user - The current user instance (see ../states/UserState.tsx) * @param userSettings - The current user settings (see ../states/SettingsState.tsx) * @param globalSettings - The global settings (see ../states/SettingsState.tsx) - * @param navigate - The navigation function (see react-router-dom) - * @param theme - The current Mantine theme - * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark') + * @param modelInformation - A dictionary of available model information + * @param renderInstance - A component function for rendering a model instance * @param host - The current host URL * @param i18n - The i18n instance for translations (from @lingui/core) * @param locale - The current locale string (e.g. 'en' / 'de') + * @param navigate - The navigation function (see react-router-dom) + * @param theme - The current Mantine theme + * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark') + * @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx) + * @param tables - A set of functions for rendering API tables + * @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx) * @param model - The model type associated with the rendered component (if applicable) - * @param modelInformation - A dictionary of available model information - * @param renderInstance - A component function for rendering a model instance * @param id - The ID (primary key) of the model instance for the plugin (if applicable) * @param instance - The model instance data (if available) * @param reloadContent - A function which can be called to reload the plugin content @@ -81,13 +106,25 @@ export type InvenTreePluginContext = { globalSettings: SettingsStateProps; modelInformation: ModelDict; renderInstance: (props: Readonly) => React.ReactNode; + renderRemoteInstance: ( + props: Readonly + ) => React.ReactNode; + renderInlineModel: ( + props: Readonly + ) => React.ReactNode; + thumbnail: (props: Readonly) => JSX.Element; host: string; i18n: I18n; locale: string; navigate: NavigateFunction; theme: MantineTheme; - forms: InvenTreeFormsContext; colorScheme: MantineColorScheme; + forms: InvenTreeFormsContext; + stateFnc: { + setRenderer: setRenderProps; + }; + tables: InvenTreeTablesContext; + importer: ImporterDrawerContext; model?: ModelType | string; id?: string | number | null; instance?: any; diff --git a/src/frontend/lib/types/Rendering.tsx b/src/frontend/lib/types/Rendering.tsx index c2f4b1e676..2ad427c519 100644 --- a/src/frontend/lib/types/Rendering.tsx +++ b/src/frontend/lib/types/Rendering.tsx @@ -1,4 +1,11 @@ +import type { + QueryObserverResult, + UseQueryResult +} from '@tanstack/react-query'; +import type { ReactNode } from 'react'; +import type { ApiEndpoints } from '..'; import type { ModelType } from '../enums/ModelType'; +import type { PathParams } from './Core'; /** * Interface for rendering a model instance. @@ -22,4 +29,57 @@ export type ModelRendererDict = EnumDictionary< export type RenderInstanceProps = { model: ModelType | undefined; + custom_model?: string; } & InstanceRenderInterface; + +export interface UseInstanceResult { + instance: any; + setInstance: (instance: any) => void; + refreshInstance: () => void; + refreshInstancePromise: () => Promise>; + instanceQuery: UseQueryResult; + isLoaded: boolean; +} + +export interface useInstanceProps { + endpoint: ApiEndpoints; + pk?: string | number | undefined; + hasPrimaryKey?: boolean; + params?: any; + pathParams?: PathParams; + disabled?: boolean; + defaultValue?: any; + refetchOnMount?: boolean; + refetchOnWindowFocus?: boolean; + updateInterval?: number; +} + +export interface RemoteInstanceProps { + model: ModelType; + modelUrl?: string; + modelRenderer?: (instance: any) => ReactNode; + pk: number; +} +export interface ThumbnailProps { + src?: string; + alt?: string; + size?: number; + text?: ReactNode; + align?: string; + link?: string; + hover?: boolean; + hoverSize?: number; +} + +export interface RenderInlineModelProps { + primary: ReactNode; + secondary?: ReactNode; + showSecondary?: boolean; + prefix?: ReactNode; + suffix?: ReactNode; + image?: string; + labels?: string[]; + url?: string; + navigate?: any; + tooltip?: string; +} diff --git a/src/frontend/lib/types/Tables.tsx b/src/frontend/lib/types/Tables.tsx index 99f02ce06d..4b3d064f79 100644 --- a/src/frontend/lib/types/Tables.tsx +++ b/src/frontend/lib/types/Tables.tsx @@ -1,10 +1,12 @@ import type { MantineStyleProp } from '@mantine/core'; +import type { AxiosInstance } from 'axios'; +import type { ShowContextMenuFunction } from 'mantine-contextmenu'; import type { DataTableCellClickHandler, DataTableRowExpansionProps } from 'mantine-datatable'; import type { ReactNode } from 'react'; -import type { NavigateFunction, SetURLSearchParams } from 'react-router-dom'; +import type { NavigateFunction } from 'react-router-dom'; import type { ModelType } from '../enums/ModelType'; import type { FilterSetState, TableFilter } from './Filters'; import type { ApiFormFieldType } from './Forms'; @@ -17,9 +19,6 @@ import type { ApiFormFieldType } from './Forms'; * isLoading: A boolean flag to indicate if the table is currently loading data * setIsLoading: A function to set the isLoading flag * filterSet: A group of active filters - * queryFilters: A map of query filters (e.g. ?active=true&overdue=false) passed in the URL - * setQueryFilters: A function to set the query filters - * clearQueryFilters: A function to clear all query filters * expandedRecords: An array of expanded records (rows) in the table * setExpandedRecords: A function to set the expanded records * isRowExpanded: A function to determine if a record is expanded @@ -49,9 +48,6 @@ export type TableState = { isLoading: boolean; setIsLoading: (value: boolean) => void; filterSet: FilterSetState; - queryFilters: URLSearchParams; - setQueryFilters: SetURLSearchParams; - clearQueryFilters: () => void; expandedRecords: any[]; setExpandedRecords: (records: any[]) => void; isRowExpanded: (pk: number) => boolean; @@ -104,7 +100,7 @@ export type TableState = { */ export type TableColumnProps = { accessor?: string; - title?: string; + title?: string | ReactNode; ordering?: string; sortable?: boolean; switchable?: boolean; @@ -177,12 +173,14 @@ export type RowViewProps = RowAction & RowModelProps; * @param barcodeActions : any[] - List of barcode actions * @param tableFilters : TableFilter[] - List of custom filters * @param tableActions : any[] - List of custom action groups + * @param isRecordSelectable : (record: any, index: number) => boolean - Callback function to determine if a row is selectable * @param detailAction: boolean - Enable detail action for each row (default = true) * @param dataFormatter : (data: any) => any - Callback function to reformat data returned by server (if not in default format) * @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions * @param onRowClick : (record: any, index: number, event: any) => void - Callback function when a row is clicked * @param onCellClick : (event: any, record: any, index: number, column: any, columnIndex: number) => void - Callback function when a cell is clicked * @param modelType: ModelType - The model type for the table + * @param height: string | number - Height of the table (default = 'auto') * @param minHeight: number - Minimum height of the table (default 300px) * @param noHeader: boolean - Hide the table header */ @@ -206,6 +204,7 @@ export type InvenTreeTableProps = { barcodeActions?: React.ReactNode[]; tableFilters?: TableFilter[]; tableActions?: React.ReactNode[]; + isRecordSelectable?: (record: T, index: number) => boolean; rowExpansion?: DataTableRowExpansionProps; dataFormatter?: (data: any) => any; rowActions?: (record: T) => RowAction[]; @@ -216,6 +215,22 @@ export type InvenTreeTableProps = { rowStyle?: (record: T, index: number) => MantineStyleProp | undefined; modelField?: string; onCellContextMenu?: (record: T, event: any) => void; + height?: string | number; minHeight?: number; noHeader?: boolean; }; + +export type InvenTreeTableRenderProps> = { + url?: string; + tableState: TableState; + tableData?: T[]; + columns: TableColumn[]; + props: InvenTreeTableProps; + api: AxiosInstance; + navigate: NavigateFunction; + + // The following attributes are for internal use only (plugins should not use these directly) + showContextMenu?: ShowContextMenuFunction; + searchParams?: URLSearchParams; + setSearchParams?: (params: URLSearchParams) => void; +}; diff --git a/src/frontend/package.json b/src/frontend/package.json index 1e6d57d0b3..dd80683ac5 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -1,7 +1,7 @@ { "name": "@inventreedb/ui", "description": "UI components for the InvenTree project", - "version": "0.7.0", + "version": "1.4.0", "private": false, "type": "module", "license": "MIT", @@ -40,14 +40,14 @@ "compile": "lingui compile --typescript" }, "dependencies": { - "@codemirror/autocomplete": "6.18.7", - "@codemirror/lang-liquid": "6.3.0", - "@codemirror/language": "6.11.3", - "@codemirror/lint": "6.8.5", - "@codemirror/search": "6.5.11", - "@codemirror/state": "6.5.2", - "@codemirror/theme-one-dark": "6.1.3", - "@codemirror/view": "6.38.2", + "@codemirror/autocomplete": "^6.20.1", + "@codemirror/lang-liquid": "^6.3.2", + "@codemirror/language": "^6.12.2", + "@codemirror/lint": "^6.9.5", + "@codemirror/search": "^6.6.0", + "@codemirror/state": "^6.6.0", + "@codemirror/theme-one-dark": "^6.1.3", + "@codemirror/view": "^6.40.0", "@emotion/react": "^11.13.3", "@fortawesome/fontawesome-svg-core": "^7.0.0", "@fortawesome/free-regular-svg-icons": "^7.0.0", @@ -58,82 +58,88 @@ "@fullcalendar/interaction": "^6.1.15", "@fullcalendar/react": "^6.1.15", "@github/webauthn-json": "^2.1.1", - "@lingui/core": "^5.3.1", - "@lingui/react": "^5.3.1", - "@mantine/carousel": "^8.2.7", - "@mantine/charts": "^8.2.7", - "@mantine/core": "^8.2.7", - "@mantine/dates": "^8.2.7", - "@mantine/dropzone": "^8.2.7", - "@mantine/form": "^8.2.7", - "@mantine/hooks": "^8.2.7", - "@mantine/modals": "^8.2.7", - "@mantine/notifications": "^8.2.7", - "@mantine/spotlight": "^8.2.7", - "@mantine/vanilla-extract": "^8.2.7", + "@lingui/core": "^5.9.2", + "@lingui/react": "^5.9.2", + "@mantine/carousel": "^9.2.1", + "@mantine/charts": "^9.2.1", + "@mantine/core": "^9.2.1", + "@mantine/dates": "^9.2.1", + "@mantine/dropzone": "^9.2.1", + "@mantine/form": "^9.2.1", + "@mantine/hooks": "^9.2.1", + "@mantine/modals": "^9.2.1", + "@mantine/notifications": "^9.2.1", + "@mantine/spotlight": "^9.2.1", + "@mantine/vanilla-extract": "^9.2.1", "@messageformat/date-skeleton": "^1.1.0", - "@sentry/react": "^10.7.0", + "@sentry/react": "^10.43.0", "@tabler/icons-react": "^3.17.0", "@tanstack/react-query": "^5.56.2", - "@uiw/codemirror-theme-vscode": "4.25.1", - "@uiw/react-codemirror": "4.25.1", - "@uiw/react-split": "^5.9.3", - "@vanilla-extract/css": "^1.17.1", - "axios": "^1.8.4", + "@uiw/codemirror-theme-vscode": "^4.25.8", + "@uiw/react-codemirror": "^4.25.8", + "@uiw/react-split": "^5.9.4", + "@vanilla-extract/css": "^1.18.0", + "axios": "^1.13.6", "clsx": "^2.1.1", - "codemirror": "6.0.2", + "codemirror": "^6.0.2", "dayjs": "^1.11.13", "dompurify": "^3.2.4", - "easymde": "^2.18.0", + "easymde": "^2.20.0", + "embla-carousel": "^8.5.2", "embla-carousel-react": "^8.5.2", "fuse.js": "^7.0.0", "html5-qrcode": "^2.3.8", - "mantine-contextmenu": "^8.2.0", - "mantine-datatable": "^8.2.0", + "mantine-contextmenu": "^9.2.1", + "mantine-datatable": "^9.2.0", "qrcode": "^1.5.4", - "react": "^19.1.2", - "react-dom": "^19.1.2", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-grid-layout": "1.4.4", "react-hook-form": "^7.62.0", - "react-is": "^19.1.2", + "react-is": "^19.2.4", "react-router-dom": "^6.26.2", "react-select": "^5.9.0", "react-simplemde-editor": "^5.2.0", "react-window": "1.8.11", "recharts": "^3.1.2", "styled-components": "^6.1.14", + "undici": "^6.24.0", "zustand": "^5.0.8" }, "devDependencies": { - "@babel/core": "^7.26.10", - "@babel/preset-react": "^7.26.3", - "@babel/preset-typescript": "^7.27.0", - "@babel/runtime": "^7.27.0", - "@codecov/vite-plugin": "^1.9.0", - "@lingui/babel-plugin-lingui-macro": "^5.3.1", - "@lingui/cli": "^5.3.1", - "@lingui/macro": "^5.3.1", - "@playwright/test": "1.56.0", - "@types/node": "^24.3.0", + "@babel/core": "^7.29.0", + "@babel/preset-react": "^7.28.5", + "@babel/preset-typescript": "^7.28.5", + "@babel/runtime": "^7.28.6", + "@codecov/vite-plugin": "^1.9.1", + "@lingui/babel-plugin-lingui-macro": "^5.9.2", + "@lingui/cli": "^5.9.2", + "@lingui/macro": "^5.9.2", + "@playwright/test": "^1.58.2", + "@types/node": "^25.5.0", "@types/qrcode": "^1.5.5", - "@types/react": "^19.1.10", - "@types/react-dom": "^19.1.7", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "@types/react-grid-layout": "^1.3.5", "@types/react-router-dom": "^5.3.3", "@types/react-window": "^1.8.8", - "@vanilla-extract/vite-plugin": "^5.1.1", - "@vitejs/plugin-react": "^5.0.2", + "@vanilla-extract/vite-plugin": "^5.1.4", + "@vitejs/plugin-react": "^5.2.0", "babel-plugin-macros": "^3.1.0", - "nyc": "^17.1.0", + "nyc": "^18.0.0", "otpauth": "^9.4.1", "path": "^0.12.7", - "rollup": "^4.0.0", - "rollup-plugin-license": "^3.5.3", - "typescript": "^5.8.2", - "vite": "7.1.11", + "rollup": "^4.59.0", + "rollup-plugin-license": "^3.7.0", + "typescript": "^5.9.3", + "vite": "^6.4.2", "vite-plugin-babel-macros": "^1.0.6", - "vite-plugin-dts": "^4.5.3", + "vite-plugin-dts": "^4.5.4", "vite-plugin-externals": "^0.6.2", - "vite-plugin-istanbul": "^6.0.2" + "vite-plugin-istanbul": "^8.0.0" + }, + "resolutions": { + "undici": "^6.24.0", + "vite": "^6.4.2" } } diff --git a/src/frontend/playwright.config.ts b/src/frontend/playwright.config.ts index 93e298eb7e..6cc8bf43f4 100644 --- a/src/frontend/playwright.config.ts +++ b/src/frontend/playwright.config.ts @@ -96,6 +96,15 @@ export default defineConfig({ stdout: 'pipe', stderr: 'pipe', timeout: 120 * 1000 + }, + { + command: 'invoke worker', + env: { + INVENTREE_DEBUG: 'True', + INVENTREE_LOG_LEVEL: 'INFO', + INVENTREE_PLUGINS_ENABLED: 'True', + INVENTREE_PLUGINS_MANDATORY: 'samplelocate' + } } ], globalSetup: './playwright/global-setup.ts', diff --git a/src/frontend/playwright/global-setup.ts b/src/frontend/playwright/global-setup.ts index 6386959cbf..4930c98b23 100644 --- a/src/frontend/playwright/global-setup.ts +++ b/src/frontend/playwright/global-setup.ts @@ -2,7 +2,13 @@ import { type FullConfig, chromium, request } from '@playwright/test'; import fs from 'node:fs'; import path from 'node:path'; -import { apiUrl } from '../tests/defaults'; +import { + adminuser, + allaccessuser, + apiUrl, + readeruser, + stevenuser +} from '../tests/defaults'; import { doCachedLogin } from '../tests/login'; async function globalSetup(config: FullConfig) { @@ -45,26 +51,22 @@ async function globalSetup(config: FullConfig) { // Perform login for each user (each in a separate browser instance) await doCachedLogin(await chromium.launch(), { - username: 'admin', - password: 'inventree', + user: adminuser, baseUrl: baseUrl }); await doCachedLogin(await chromium.launch(), { - username: 'allaccess', - password: 'nolimits', + user: allaccessuser, baseUrl: baseUrl }); await doCachedLogin(await chromium.launch(), { - username: 'reader', - password: 'readonly', + user: readeruser, baseUrl: baseUrl }); await doCachedLogin(await chromium.launch(), { - username: 'steven', - password: 'wizardstaff', + user: stevenuser, baseUrl: baseUrl }); } diff --git a/src/frontend/src/components/barcodes/BarcodeInput.tsx b/src/frontend/src/components/barcodes/BarcodeInput.tsx index 6e5d5e012b..4fa4dd03b8 100644 --- a/src/frontend/src/components/barcodes/BarcodeInput.tsx +++ b/src/frontend/src/components/barcodes/BarcodeInput.tsx @@ -13,9 +13,9 @@ import { import { IconCamera, IconScan } from '@tabler/icons-react'; import { useCallback, useMemo, useState } from 'react'; +import { Boundary } from '@lib/components/Boundary'; import { useLocalStorage } from '@mantine/hooks'; import { useGlobalSettingsState } from '../../states/SettingsStates'; -import { Boundary } from '../Boundary'; import BarcodeCameraInput from './BarcodeCameraInput'; import BarcodeKeyboardInput from './BarcodeKeyboardInput'; diff --git a/src/frontend/src/components/barcodes/BarcodeScanDialog.tsx b/src/frontend/src/components/barcodes/BarcodeScanDialog.tsx index 6e2eb50640..1e3cbce14e 100644 --- a/src/frontend/src/components/barcodes/BarcodeScanDialog.tsx +++ b/src/frontend/src/components/barcodes/BarcodeScanDialog.tsx @@ -1,3 +1,4 @@ +import { StylishText } from '@lib/components/StylishText'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelInformationDict } from '@lib/enums/ModelInformation'; import type { ModelType } from '@lib/enums/ModelType'; @@ -11,7 +12,6 @@ import { type NavigateFunction, useNavigate } from 'react-router-dom'; import { api } from '../../App'; import { extractErrorMessage } from '../../functions/api'; import { useUserState } from '../../states/UserState'; -import { StylishText } from '../items/StylishText'; import { BarcodeInput } from './BarcodeInput'; export type BarcodeScanResult = { diff --git a/src/frontend/src/components/barcodes/QRCode.tsx b/src/frontend/src/components/barcodes/QRCode.tsx index fd8e0a1387..11155e5d8f 100644 --- a/src/frontend/src/components/barcodes/QRCode.tsx +++ b/src/frontend/src/components/barcodes/QRCode.tsx @@ -18,11 +18,11 @@ import { useQuery } from '@tanstack/react-query'; import QR from 'qrcode'; import { useCallback, useEffect, useMemo, useState } from 'react'; +import { CopyButton } from '@lib/components/CopyButton'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { apiUrl } from '@lib/functions/Api'; import { api } from '../../App'; import { useGlobalSettingsState } from '../../states/SettingsStates'; -import { CopyButton } from '../buttons/CopyButton'; import type { QrCodeType } from '../items/ActionDropdown'; import { extractErrorMessage } from '../../functions/api'; diff --git a/src/frontend/src/components/buttons/PrimaryActionButton.tsx b/src/frontend/src/components/buttons/PrimaryActionButton.tsx index 275fd21379..293d3b0b8b 100644 --- a/src/frontend/src/components/buttons/PrimaryActionButton.tsx +++ b/src/frontend/src/components/buttons/PrimaryActionButton.tsx @@ -12,7 +12,8 @@ export default function PrimaryActionButton({ icon, color, hidden, - onClick + onClick, + leftSection }: Readonly<{ title: string; tooltip?: string; @@ -20,6 +21,7 @@ export default function PrimaryActionButton({ color?: string; hidden?: boolean; onClick: () => void; + leftSection?: React.ReactNode; }>) { if (hidden) { return null; @@ -28,7 +30,7 @@ export default function PrimaryActionButton({ return (

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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/stock/transfer_order_display.png b/docs/docs/assets/images/stock/transfer_order_display.png new file mode 100644 index 0000000000000000000000000000000000000000..c1e0bcb335f1de15ed50797d6d212a6855f7d4e3 GIT binary patch literal 89501 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